This patch to the C++ frontend uses the BLT infrastructure to improve: extern int callee_1 (int one, const char *two, float three);
int test_1 (int first, int second, float third) { return callee_1 (first, second, third); } from: error: invalid conversion from 'int' to 'const char*' [-fpermissive] return callee_1 (first, second, third); ^ note: initializing argument 2 of 'int callee_1(int, const char*, float)' extern int callee_1 (int one, const char *two, float three); ^~~~~~~~ to: error: invalid conversion from 'int' to 'const char*' [-fpermissive] return callee_1 (first, second, third); ^ note: initializing argument 2 of 'int callee_1(int, const char*, float)' extern int callee_1 (int one, const char *two, float three); ^~~~~~~~~~~~~~~ by locating the pertinent parameter within the decl, by traversing the BLT tree (if present). gcc/cp/ChangeLog: * call.c: Include "blt.h". (get_blt_node_for_function_decl): New function. (get_fndecl_argument_location): New function. (convert_like_real): Use the above when determining the location for the note about a mismatching argument. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/param-type-mismatch.C: Add -fblt to the options. Update expected output to show that the pertinent callee parameters are underlined. --- gcc/cp/call.c | 79 +++++++++++++++++++++- .../g++.dg/diagnostic/param-type-mismatch.C | 21 +++--- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index fac6b6c..99693df 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "c-family/c-objc.h" #include "internal-fn.h" +#include "blt.h" /* The various kinds of conversion. */ @@ -6590,6 +6591,77 @@ maybe_print_user_conv_context (conversion *convs) } } +/* Attempt to locate the blt_node for FNDECL, or return NULL + if not found (or blt was not enabled). */ + +static blt_node * +get_blt_node_for_function_decl (tree fndecl) +{ + if (!flag_blt) + return NULL; + + blt_node *node = blt_get_node_for_tree (fndecl); + if (node) + return node; + + tree template_decl = DECL_TI_TEMPLATE (fndecl); + if (template_decl) + { + node = blt_get_node_for_tree (template_decl); + if (node) + return node; + } + + return NULL; +} + +/* Attempt to locate the parameter with the given index within + FNDECL, returning DECL_SOURCE_LOCATION (fndecl) if it can't + be found (or blt was not enabled). */ + +static location_t +get_fndecl_argument_location (tree fndecl, int argnum) +{ + location_t loc = DECL_SOURCE_LOCATION (fndecl); + blt_node *node = get_blt_node_for_function_decl (fndecl); + if (!node) + return loc; + + /* For "member-declaration", expect the "direct-declarator" to be + inside a "declarator". */ + if (node->get_kind () == BLT_MEMBER_DECLARATION) + { + node = node->get_first_child_of_kind (BLT_DECLARATOR); + if (!node) + return loc; + node = node->get_first_child_of_kind (BLT_DIRECT_DECLARATOR); + if (!node) + return loc; + } + + if (node->get_kind () != BLT_DIRECT_DECLARATOR) + return loc; + + blt_node *pdc + = node->get_first_child_of_kind (BLT_PARAMETER_DECLARATION_CLAUSE); + if (!pdc) + return loc; + + blt_node *pdl = pdc->get_first_child_of_kind (BLT_PARAMETER_DECLARATION_LIST); + if (!pdl) + return loc; + + auto_vec<blt_node *> params; + pdl->get_children_of_kind (params, BLT_PARAMETER_DECLARATION); + + if (argnum >= (int)params.length ()) + return loc; + + blt_node *param = params[argnum]; + return param->get_range (); +} + + /* Perform the conversions in CONVS on the expression EXPR. FN and ARGNUM are used for diagnostics. ARGNUM is zero based, -1 indicates the `this' argument of a method. INNER is nonzero when @@ -6691,8 +6763,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, complained = permerror (loc, "invalid conversion from %qH to %qI", TREE_TYPE (expr), totype); if (complained && fn) - inform (DECL_SOURCE_LOCATION (fn), - " initializing argument %P of %qD", argnum, fn); + { + location_t decl_loc = get_fndecl_argument_location (fn, argnum); + inform (decl_loc, + " initializing argument %P of %qD", argnum, fn); + } return cp_convert (totype, expr, complain); } diff --git a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C index 864ead1..5c89098 100644 --- a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C +++ b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C @@ -1,12 +1,9 @@ -// { dg-options "-fdiagnostics-show-caret" } +// { dg-options "-fdiagnostics-show-caret -fblt" } /* A collection of calls where argument 2 is of the wrong type. TODO: we should put the caret and underline for the diagnostic - at the second argument, rather than the close paren. - - TODO: we should highlight the second parameter of the callee, rather - than its name. */ + at the second argument, rather than the close paren. */ /* decl, with argname. */ @@ -22,7 +19,7 @@ int test_1 (int first, int second, float third) // { 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 "" } */ } @@ -40,7 +37,7 @@ int test_2 (int first, int second, float third) // { 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 "" } */ } @@ -61,7 +58,7 @@ int test_3 (int first, int second, float third) // { 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 "" } */ } @@ -78,7 +75,7 @@ int test_4 (int first, int second, float third) { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } struct s4 { static int member_1 (int one, const char *two, float three); }; - ^~~~~~~~ + ^~~~~~~~~~~~~~~ { dg-end-multiline-output "" } */ } @@ -96,7 +93,7 @@ int test_5 (int first, int second, float third) { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } struct s5 { int member_1 (int one, const char *two, float three); }; - ^~~~~~~~ + ^~~~~~~~~~~~~~~ { dg-end-multiline-output "" } */ } @@ -136,7 +133,7 @@ int test_7 (int first, int second, float third) { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } struct s7 { static int member_1 (int one, T two, float three); }; - ^~~~~~~~ + ^~~~~ { dg-end-multiline-output "" } */ } @@ -155,7 +152,7 @@ int test_8 (int first, int second, float third) { dg-end-multiline-output "" } */ /* { dg-begin-multiline-output "" } struct s8 { int member_1 (int one, T two, float three); }; - ^~~~~~~~ + ^~~~~ { dg-end-multiline-output "" } */ } -- 1.8.5.3