From: David Malcolm Date: Fri, 30 Nov 2018 22:51:18 +0000 (+0000) Subject: C++: fix-it hint for missing parentheses X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8ba109cecce1cf6598380908a1d6b00e0360b85d;p=gcc.git C++: fix-it hint for missing parentheses 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. 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. From-SVN: r266696 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58b58865933..bda587bbfff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-11-30 David Malcolm + + * diagnostic-core.h (emit_diagnostic): New decl. + * diagnostic.c (emit_diagnostic): New overload, taking a + rich_location *. + 2018-11-30 David Malcolm * pretty-print.c (class selftest::test_pretty_printer): New diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c8b7d10ae4..dbe4ad30bdb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-11-30 David Malcolm + + * 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. + 2018-11-30 James Norris * parser.c (cp_parser_oacc_enter_exit_data): Use existing local diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d0b12352a05..64e36efd17e 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 80ff39541e6..6c40f26acb5 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 1b572aec6de..d97e9592f06 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -1200,6 +1200,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/ChangeLog b/gcc/testsuite/ChangeLog index 1c6a9561378..c5b551319ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-11-30 David Malcolm + + * g++.dg/parse/missing-parens-fixit.C: New test. + 2018-11-30 Michael Ploujnikov * gcc.dg/independent-cloneids-1.c: New test. 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 00000000000..a0fd7dd2511 --- /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 "" } */ +}