Commit 8ba109ce by David Malcolm Committed by David Malcolm

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
parent 553a316b
2018-11-30 David Malcolm <dmalcolm@redhat.com> 2018-11-30 David Malcolm <dmalcolm@redhat.com>
* diagnostic-core.h (emit_diagnostic): New decl.
* diagnostic.c (emit_diagnostic): New overload, taking a
rich_location *.
2018-11-30 David Malcolm <dmalcolm@redhat.com>
* pretty-print.c (class selftest::test_pretty_printer): New * pretty-print.c (class selftest::test_pretty_printer): New
subclass of pretty_printer. subclass of pretty_printer.
(selftest::test_prefixes_and_wrapping): New test. (selftest::test_prefixes_and_wrapping): New test.
2018-11-30 David Malcolm <dmalcolm@redhat.com>
* 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 <jnorris@codesourcery.com> 2018-11-30 James Norris <jnorris@codesourcery.com>
* parser.c (cp_parser_oacc_enter_exit_data): Use existing local * parser.c (cp_parser_oacc_enter_exit_data): Use existing local
......
...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h" #include "stor-layout.h"
#include "varasm.h" #include "varasm.h"
#include "intl.h" #include "intl.h"
#include "gcc-rich-location.h"
static tree static tree
process_init_constructor (tree type, tree init, int nested, process_init_constructor (tree type, tree init, int nested,
...@@ -507,9 +508,16 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value, ...@@ -507,9 +508,16 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
if (DECL_FUNCTION_MEMBER_P (member) if (DECL_FUNCTION_MEMBER_P (member)
&& ! flag_ms_extensions) && ! flag_ms_extensions)
emit_diagnostic (diag_kind, loc, 0, {
"invalid use of member function %qD " gcc_rich_location richloc (loc);
"(did you forget the %<()%> ?)", member); /* 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 else
emit_diagnostic (diag_kind, loc, 0, emit_diagnostic (diag_kind, loc, 0,
"invalid use of member %qD " "invalid use of member %qD "
......
...@@ -105,6 +105,8 @@ extern void inform_n (location_t, unsigned HOST_WIDE_INT, const char *, ...@@ -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 void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern bool emit_diagnostic (diagnostic_t, location_t, int, extern bool emit_diagnostic (diagnostic_t, location_t, int,
const char *, ...) ATTRIBUTE_GCC_DIAG(4,5); 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 *, extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *,
va_list *) ATTRIBUTE_GCC_DIAG (4,0); va_list *) ATTRIBUTE_GCC_DIAG (4,0);
extern bool seen_error (void); extern bool seen_error (void);
......
...@@ -1200,6 +1200,20 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt, ...@@ -1200,6 +1200,20 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt,
return ret; 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. */ /* Wrapper around diagnostic_impl taking a va_list parameter. */
bool bool
......
2018-11-30 David Malcolm <dmalcolm@redhat.com>
* g++.dg/parse/missing-parens-fixit.C: New test.
2018-11-30 Michael Ploujnikov <michael.ploujnikov@oracle.com> 2018-11-30 Michael Ploujnikov <michael.ploujnikov@oracle.com>
* gcc.dg/independent-cloneids-1.c: New test. * gcc.dg/independent-cloneids-1.c: New test.
......
// { 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 "" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment