[PATCH] C++: fix-it hint for missing parentheses
David Malcolm
dmalcolm@redhat.com
Mon Nov 12 02:28:00 GMT 2018
Consider:
class t1
{
public:
double length () const { return m_length; }
private:
double m_length;
};
missing-parens-fixit.C: In function 'bool test_1(const t1&)':
missing-parens-fixit.C:14:15: error: invalid use of member function
'double t1::length() const' (did you forget the '()' ?)
14 | return inst.length > 0.0;
| ~~~~~^~~~~~
This patch adds a fix-it hint for the case where the member function
takes no parameters, suggesting the addition of the parentheses:
14 | return inst.length > 0.0;
| ~~~~~^~~~~~
| ()
so that an IDE can potentially apply the fix.
OK for trunk?
gcc/cp/ChangeLog:
* typeck2.c: Include "gcc-rich-location.h".
(cxx_incomplete_type_diagnostic): When complaining about possibly
missing parens, add a fix-it hint if the member function takes no
additional params.
gcc/ChangeLog:
* diagnostic-core.h (emit_diagnostic): New decl.
* diagnostic.c (emit_diagnostic): New overload, taking a
rich_location *.
gcc/testsuite/ChangeLog:
* g++.dg/parse/missing-parens-fixit.C: New test.
---
gcc/cp/typeck2.c | 14 +++++++---
gcc/diagnostic-core.h | 2 ++
gcc/diagnostic.c | 14 ++++++++++
gcc/testsuite/g++.dg/parse/missing-parens-fixit.C | 32 +++++++++++++++++++++++
4 files changed, 59 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/parse/missing-parens-fixit.C
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index fec1db0..c3c59a8 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h"
#include "varasm.h"
#include "intl.h"
+#include "gcc-rich-location.h"
static tree
process_init_constructor (tree type, tree init, int nested,
@@ -507,9 +508,16 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
if (DECL_FUNCTION_MEMBER_P (member)
&& ! flag_ms_extensions)
- emit_diagnostic (diag_kind, loc, 0,
- "invalid use of member function %qD "
- "(did you forget the %<()%> ?)", member);
+ {
+ gcc_rich_location richloc (loc);
+ /* If "member" has no arguments (other than "this"), then
+ add a fix-it hint. */
+ if (type_num_arguments (TREE_TYPE (member)) == 1)
+ richloc.add_fixit_insert_after ("()");
+ emit_diagnostic (diag_kind, &richloc, 0,
+ "invalid use of member function %qD "
+ "(did you forget the %<()%> ?)", member);
+ }
else
emit_diagnostic (diag_kind, loc, 0,
"invalid use of member %qD "
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index 80ff395..6c40f26 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -105,6 +105,8 @@ extern void inform_n (location_t, unsigned HOST_WIDE_INT, const char *,
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern bool emit_diagnostic (diagnostic_t, location_t, int,
const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
+extern bool emit_diagnostic (diagnostic_t, rich_location *, int,
+ const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *,
va_list *) ATTRIBUTE_GCC_DIAG (4,0);
extern bool seen_error (void);
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index a572c08..9b583ce 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -1168,6 +1168,20 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt,
return ret;
}
+/* As above, but for rich_location *. */
+
+bool
+emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
+ const char *gmsgid, ...)
+{
+ auto_diagnostic_group d;
+ va_list ap;
+ va_start (ap, gmsgid);
+ bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, kind);
+ va_end (ap);
+ return ret;
+}
+
/* Wrapper around diagnostic_impl taking a va_list parameter. */
bool
diff --git a/gcc/testsuite/g++.dg/parse/missing-parens-fixit.C b/gcc/testsuite/g++.dg/parse/missing-parens-fixit.C
new file mode 100644
index 0000000..a0fd7dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/missing-parens-fixit.C
@@ -0,0 +1,32 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+class t1
+{
+public:
+ double length () const { return m_length; }
+ double area (double width) const { return m_length * width; }
+
+private:
+ double m_length;
+};
+
+bool test_1 (const t1 &inst)
+{
+ return inst.length > 0.0; // { dg-error "did you forget the '\\(\\)'" }
+ /* We expect a fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ return inst.length > 0.0;
+ ~~~~~^~~~~~
+ ()
+ { dg-end-multiline-output "" } */
+}
+
+bool test_2 (const t1 &inst)
+{
+ return inst.area > 0.0; // { dg-error "did you forget the '\\(\\)'" }
+ /* "t1::area" has additional params, so we don't expect a fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ return inst.area > 0.0;
+ ~~~~~^~~~
+ { dg-end-multiline-output "" } */
+}
--
1.8.5.3
More information about the Gcc-patches
mailing list