[PATCH 07/17] C++: use BLT to highlight parameter of callee decl for mismatching types
David Malcolm
dmalcolm@redhat.com
Mon Jul 24 19:38:00 GMT 2017
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
More information about the Gcc-patches
mailing list