On Thu, 2018-03-29 at 09:20 -0400, Jason Merrill wrote:
> On Wed, Mar 28, 2018 at 4:44 PM, David Malcolm <[email protected]>
> 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