On Thu, 2018-03-29 at 09:20 -0400, Jason Merrill wrote: > On Wed, Mar 28, 2018 at 4:44 PM, David Malcolm <dmalc...@redhat.com> > wrote: > > This followup patch updates the specific error-handling path > > to add a note showing the pertinent parameter decl, taking > > the output from: > > > > test.cc: In function 'void caller(const char*)': > > test.cc:6:14: error: cannot convert 'const char*' to 'const char**' > > for argument '2' to 'void callee(int, const char**, int)' > > callee (1, fmt, 3); > > ^~~ > > > > to: > > > > test.cc: In function 'void caller(const char*)': > > test.cc:6:14: error: cannot convert 'const char*' to 'const char**' > > for argument '2' to 'void callee(int, const char**, int)' > > callee (1, fmt, 3); > > ^~~ > > test.cc:1:36: note: initializing argument 2 of 'void callee(int, > > const char**, int)' > > void callee (int one, const char **two, int three); > > ~~~~~~~~~~~~~^~~ > > > > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; adds > > a further 18 PASS results to g++.sum. > > > > Again, not a regression as such, but I've been calling out the > > underlined > > arguments as a feature of gcc 8, so would be good to fix. > > > > OK for trunk? > > > > gcc/cp/ChangeLog: > > PR c++/85110 > > * call.c (get_fndecl_argument_location): Make non-static. > > * cp-tree.h (get_fndecl_argument_location): New decl. > > * typeck.c (convert_for_assignment): When complaining due > > to > > conversions for an argument, show the location of the > > parameter > > within the decl. > > > > gcc/testsuite/ChangeLog: > > PR c++/85110 > > * g++.dg/diagnostic/param-type-mismatch-2.C: Update for the > > cases > > where we now show the pertinent parameter. > > --- > > gcc/cp/call.c | 2 +- > > gcc/cp/cp-tree.h | 2 ++ > > gcc/cp/typeck.c | 10 +++++++ > > --- > > .../g++.dg/diagnostic/param-type-mismatch-2.C | 21 > > ++++++++++++++++++--- > > 4 files changed, 28 insertions(+), 7 deletions(-) > > > > diff --git a/gcc/cp/call.c b/gcc/cp/call.c > > index 1a87f99..e1a0639 100644 > > --- a/gcc/cp/call.c > > +++ b/gcc/cp/call.c > > @@ -6598,7 +6598,7 @@ maybe_print_user_conv_context (conversion > > *convs) > > ARGNUM is zero based, -1 indicates the `this' argument of a > > method. > > Return the location of the FNDECL itself if there are > > problems. */ > > > > -static location_t > > +location_t > > get_fndecl_argument_location (tree fndecl, int argnum) > > { > > int i; > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > > index d5382c2..b45880d 100644 > > --- a/gcc/cp/cp-tree.h > > +++ b/gcc/cp/cp-tree.h > > @@ -5965,6 +5965,8 @@ extern bool > > can_convert_arg (tree, tree, tree, int, > > tsubst_flags_t); > > extern bool can_convert_arg_bad (tree, > > tree, tree, int, > > tsubst_flags_t); > > +extern location_t get_fndecl_argument_location (tree, int); > > + > > > > /* A class for recording information about access failures (e.g. > > private > > fields), so that we can potentially supply a fix-it hint about > > diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c > > index e733c79..742b2e9 100644 > > --- a/gcc/cp/typeck.c > > +++ b/gcc/cp/typeck.c > > @@ -8781,9 +8781,13 @@ convert_for_assignment (tree type, tree rhs, > > parmnum, > > complain, flags); > > } > > else if (fndecl) > > - error_at (EXPR_LOC_OR_LOC (rhs, input_location), > > - "cannot convert %qH to %qI for argument > > %qP to %qD", > > - rhstype, type, parmnum, fndecl); > > + { > > + error_at (EXPR_LOC_OR_LOC (rhs, input_location), > > + "cannot convert %qH to %qI for argument > > %qP to %qD", > > + rhstype, type, parmnum, fndecl); > > + inform (get_fndecl_argument_location (fndecl, > > parmnum), > > + " initializing argument %P of %qD", > > parmnum, fndecl); > > If you're adding the inform, you don't need the %P of %D in the > initial error. > > Jason
Thanks. Here's an updated version of the patch which removes them. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; adds 18 PASS results to g++.sum. OK for trunk? gcc/cp/ChangeLog: PR c++/85110 * call.c (get_fndecl_argument_location): Make non-static. * cp-tree.h (get_fndecl_argument_location): New decl. * typeck.c (convert_for_assignment): When complaining due to conversions for an argument, show the location of the parameter within the decl. gcc/testsuite/ChangeLog: PR c++/85110 * g++.dg/cpp1z/direct-enum-init1.C: Update for the cases where we now show the pertinent parameter. * g++.dg/diagnostic/aka2.C: Likewise. * g++.dg/diagnostic/param-type-mismatch-2.C: Likewise. --- gcc/cp/call.c | 2 +- gcc/cp/cp-tree.h | 2 ++ gcc/cp/typeck.c | 10 +++++--- gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C | 6 ++--- gcc/testsuite/g++.dg/diagnostic/aka2.C | 2 +- .../g++.dg/diagnostic/param-type-mismatch-2.C | 27 +++++++++++++++++----- 6 files changed, 35 insertions(+), 14 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f2ada27..53850c1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6595,7 +6595,7 @@ maybe_print_user_conv_context (conversion *convs) ARGNUM is zero based, -1 indicates the `this' argument of a method. Return the location of the FNDECL itself if there are problems. */ -static location_t +location_t get_fndecl_argument_location (tree fndecl, int argnum) { int i; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dbe34c0..0538351 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5994,6 +5994,8 @@ extern bool can_convert_arg (tree, tree, tree, int, tsubst_flags_t); extern bool can_convert_arg_bad (tree, tree, tree, int, tsubst_flags_t); +extern location_t get_fndecl_argument_location (tree, int); + /* A class for recording information about access failures (e.g. private fields), so that we can potentially supply a fix-it hint about diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e5ad54d..b449b1f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8785,9 +8785,13 @@ convert_for_assignment (tree type, tree rhs, parmnum, complain, flags); } else if (fndecl) - error_at (EXPR_LOC_OR_LOC (rhs, input_location), - "cannot convert %qH to %qI for argument %qP to %qD", - rhstype, type, parmnum, fndecl); + { + error_at (EXPR_LOC_OR_LOC (rhs, input_location), + "cannot convert %qH to %qI", + rhstype, type); + inform (get_fndecl_argument_location (fndecl, parmnum), + " initializing argument %P of %qD", parmnum, fndecl); + } else switch (errtype) { diff --git a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C index d8cffb4..fa2934e 100644 --- a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C +++ b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C @@ -40,7 +40,7 @@ foo () D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++17 } .-1 } - bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } + bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E'" } bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } @@ -106,7 +106,7 @@ foo2 () D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++17 } .-1 } - bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } + bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E'" } bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } @@ -174,7 +174,7 @@ foo3 () K *d7 = new K { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } L *e5 = new L { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++17 } .-1 } - bar3 ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } + bar3 ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E'" } bar3 (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } M v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } M v2 = { L { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } diff --git a/gcc/testsuite/g++.dg/diagnostic/aka2.C b/gcc/testsuite/g++.dg/diagnostic/aka2.C index a43f9e3..d7a3b35 100644 --- a/gcc/testsuite/g++.dg/diagnostic/aka2.C +++ b/gcc/testsuite/g++.dg/diagnostic/aka2.C @@ -11,7 +11,7 @@ int foo(t1 *); void test_1 () { t2 pos; - foo (&pos); // { dg-error "cannot convert 't2\\*' {aka 's2\\*'} to 't1\\*' {aka 's1\\*'} for argument '1' to 'int foo\\(t1\\*\\)'" } + foo (&pos); // { dg-error "cannot convert 't2\\*' {aka 's2\\*'} to 't1\\*' {aka 's1\\*'}" } } /* Exercise %T. */ 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 ae84248..c3b6f00 100644 --- a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C +++ b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C @@ -4,44 +4,59 @@ /* decl, with argname. */ -extern int callee_1 (int one, const char **two, float three); +extern int callee_1 (int one, const char **two, float three); // { dg-line callee_1 } int test_1 (int first, const char *second, float third) { - return callee_1 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*' for argument '2' to 'int callee_1\\(int, const char\\*\\*, float\\)'" } + return callee_1 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*'" } /* { dg-begin-multiline-output "" } return callee_1 (first, second, third); ^~~~~~ { dg-end-multiline-output "" } */ + // { dg-message "initializing argument 2 of 'int callee_1\\(int, const char\\*\\*, float\\)'" "" { target *-*-* } callee_1 } + /* { dg-begin-multiline-output "" } + extern int callee_1 (int one, const char **two, float three); + ~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ } /* decl, without argname. */ -extern int callee_2 (int, const char **, float); +extern int callee_2 (int, const char **, float); // { dg-line callee_2 } int test_2 (int first, const char *second, float third) { - return callee_2 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*' for argument '2' to 'int callee_2\\(int, const char\\*\\*, float\\)'" } + return callee_2 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*'" } /* { dg-begin-multiline-output "" } return callee_2 (first, second, third); ^~~~~~ { dg-end-multiline-output "" } */ + // { dg-message "initializing argument 2 of 'int callee_2\\(int, const char\\*\\*, float\\)'" "" { target *-*-* } callee_2 } + /* { dg-begin-multiline-output "" } + extern int callee_2 (int, const char **, float); + ^~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ } /* defn, with argname. */ -static int callee_3 (int one, const char **two, float three) +static int callee_3 (int one, const char **two, float three) // { dg-line callee_3 } { return callee_2 (one, two, three); } int test_3 (int first, const char *second, float third) { - return callee_3 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*' for argument '2' to 'int callee_3\\(int, const char\\*\\*, float\\)'" } + return callee_3 (first, second, third); // { dg-error "27: cannot convert 'const char\\*' to 'const char\\*\\*'" } /* { dg-begin-multiline-output "" } return callee_3 (first, second, third); ^~~~~~ { dg-end-multiline-output "" } */ + // { dg-message "initializing argument 2 of 'int callee_3\\(int, const char\\*\\*, float\\)'" "" { target *-*-* } callee_3 } + /* { dg-begin-multiline-output "" } + static int callee_3 (int one, const char **two, float three) + ~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ } /* static member, with argname. */ -- 1.8.5.3