Consider this bogus code (from g++.dg/diagnostic/param-type-mismatch-2.C):

struct s4 { static int member_1 (int one, const char **two, float three); };

int test_4 (int first, const char *second, float third)
{
  return s4::member_1 (first, second, third);
}

Before this patch, g++ emits:

demo.cc: In function 'int test_4(int, const char*, float)':
demo.cc:5:44: error: no matching function for call to 's4::member_1(int&, const 
char*&, float&)'
5 |   return s4::member_1 (first, second, third);
  |                                            ^
demo.cc:1:24: note: candidate: 'static int s4::member_1(int, const char**, 
float)'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                        ^~~~~~~~
demo.cc:1:24: note:   no known conversion for argument 2 from 'const char*' to 
'const char**'

With this patch, it highlights the pertinent parameter in the
"no known conversion" note:

demo.cc: In function 'int test_4(int, const char*, float)':
demo.cc:5:44: error: no matching function for call to 's4::member_1(int&, const 
char*&, float&)'
5 |   return s4::member_1 (first, second, third);
  |                                            ^
demo.cc:1:24: note: candidate: 'static int s4::member_1(int, const char**, 
float)'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                        ^~~~~~~~
demo.cc:1:56: note:   no known conversion for argument 2 from 'const char*' to 
'const char**'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                                           ~~~~~~~~~~~~~^~~

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; adds
15 PASS results to g++.sum.

OK for trunk?

I'm working on a followup to highlight the pertinent argument
in the initial error diagnostic.

gcc/cp/ChangeLog:
        PR c++/85110
        * call.c (print_conversion_rejection): Add "fn" param and use it
        for "no known conversion" messages to underline the pertinent
        param.
        (print_z_candidate): Supply "fn" to the new param above.

gcc/testsuite/ChangeLog:
        PR c++/85110
        * g++.dg/diagnostic/param-type-mismatch-2.C: Update expected
        output to reflect underlining of pertinent parameter in decl
        for "no known conversion" messages.
---
 gcc/cp/call.c                                      | 17 +++++++++------
 .../g++.dg/diagnostic/param-type-mismatch-2.C      | 25 +++++++++++++++++-----
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 626830c..ef445e0 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3432,10 +3432,11 @@ equal_functions (tree fn1, tree fn2)
   return fn1 == fn2;
 }
 
-/* Print information about a candidate being rejected due to INFO.  */
+/* Print information about a candidate FN being rejected due to INFO.  */
 
 static void
-print_conversion_rejection (location_t loc, struct conversion_info *info)
+print_conversion_rejection (location_t loc, struct conversion_info *info,
+                           tree fn)
 {
   tree from = info->from;
   if (!TYPE_P (from))
@@ -3466,8 +3467,12 @@ print_conversion_rejection (location_t loc, struct 
conversion_info *info)
     inform (loc, "  no known conversion from %qH to %qI",
            from, info->to_type);
   else
-    inform (loc, "  no known conversion for argument %d from %qH to %qI",
-           info->n_arg + 1, from, info->to_type);
+    {
+      if (TREE_CODE (fn) == FUNCTION_DECL)
+       loc = get_fndecl_argument_location (fn, info->n_arg);
+      inform (loc, "  no known conversion for argument %d from %qH to %qI",
+             info->n_arg + 1, from, info->to_type);
+    }
 }
 
 /* Print information about a candidate with WANT parameters and we found
@@ -3542,10 +3547,10 @@ print_z_candidate (location_t loc, const char *msgstr,
                                   r->u.arity.expected);
          break;
        case rr_arg_conversion:
-         print_conversion_rejection (cloc, &r->u.conversion);
+         print_conversion_rejection (cloc, &r->u.conversion, fn);
          break;
        case rr_bad_arg_conversion:
-         print_conversion_rejection (cloc, &r->u.bad_conversion);
+         print_conversion_rejection (cloc, &r->u.bad_conversion, fn);
          break;
        case rr_explicit_conversion:
          inform (cloc, "  return type %qT of explicit conversion function "
diff --git a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C 
b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C
index 8cf2dab..4957f61 100644
--- a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C
+++ b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C
@@ -82,7 +82,10 @@ int test_4 (int first, const char *second, float third)
                         ^~~~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "no known conversion for argument 2 from 'const char\\*' to 
'const char\\*\\*'" "" { target *-*-* } s4_member_1 }
-  // TODO: underline the pertinent param
+  /* { dg-begin-multiline-output "" } 
+ struct s4 { static int member_1 (int one, const char **two, float three); };
+                                           ~~~~~~~~~~~~~^~~
+     { dg-end-multiline-output "" } */
 }
 
 /* non-static member, with argname.  */
@@ -103,7 +106,10 @@ int test_5 (int first, const char *second, float third)
                  ^~~~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "no known conversion for argument 2 from 'const char\\*' to 
'const char\\*\\*'" "" { target *-*-* } s5_member_1 }
-  // TODO: underline the pertinent param
+  /* { dg-begin-multiline-output "" } 
+ struct s5 { int member_1 (int one, const char **two, float three); };
+                                    ~~~~~~~~~~~~~^~~
+     { dg-end-multiline-output "" } */
 }
 
 /* non-static member, with argname, via a ptr.  */
@@ -123,7 +129,10 @@ int test_6 (int first, const char *second, float third, s6 
*ptr)
                  ^~~~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "no known conversion for argument 2 from 'const char\\*' to 
'const char\\*\\*'" "" { target *-*-* } s6_member_1 }
-  // TODO: underline the pertinent param
+  /* { dg-begin-multiline-output "" } 
+ struct s6 { int member_1 (int one, const char **two, float three); };
+                                    ~~~~~~~~~~~~~^~~
+     { dg-end-multiline-output "" } */
 }
 
 /* Template function.  */
@@ -170,7 +179,10 @@ int test_8 (int first, const char *second, float third)
                         ^~~~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "no known conversion for argument 2 from 'const char\\*' to 
'const char\\*\\*'" "" { target *-*-* } s8_member_1 }
-  // TODO: underline the pertinent param
+  /* { dg-begin-multiline-output "" }
+ struct s8 { static int member_1 (int one, T two, float three); };
+                                           ~~^~~
+     { dg-end-multiline-output "" } */
 }
 
 /* Template class, non-static function.  */
@@ -192,5 +204,8 @@ int test_9 (int first, const char *second, float third)
                  ^~~~~~~~
      { dg-end-multiline-output "" } */
   // { dg-message "no known conversion for argument 2 from 'const char\\*' to 
'const char\\*\\*'" "" { target *-*-* } s9_member_1 }
-  // TODO: underline the pertinent param
+  /* { dg-begin-multiline-output "" }
+ struct s9 { int member_1 (int one, T two, float three); };
+                                    ~~^~~
+     { dg-end-multiline-output "" } */
 }
-- 
1.8.5.3

Reply via email to