diff mbox

[10/17] C++: provide fix-it hints in -Wsuggest-override

Message ID 1500926714-56988-11-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm July 24, 2017, 8:05 p.m. UTC
This patch to the C++ frontend extends -Wsuggest-override so that the
suggestions contain fix-it hints, provided that it can get at the correct
location.  Doing so requires the blt_node infrastructure.

gcc/cp/ChangeLog:
	* class.c: Include "gcc-rich-location.h" and "blt.h".
	(check_for_override): When suggesting functions that can be marked
	"override", if the location is available via BLT nodes, add a
	fix-it hint.

gcc/testsuite/ChangeLog:
	* g++.dg/warn/Wsuggest-override.C: Add -fdiagnostics-show-caret and
	-fblt to the options.  Update expected output to show the fix-it
	hints.
---
 gcc/cp/class.c                                | 23 +++++++++++++++++++++--
 gcc/testsuite/g++.dg/warn/Wsuggest-override.C | 12 +++++++++++-
 2 files changed, 32 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0336ae5..6d0644d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -37,6 +37,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 #include "intl.h"
 #include "asan.h"
+#include "gcc-rich-location.h"
+#include "blt.h"
 
 /* Id for dumping the class hierarchy.  */
 int class_dump_id;
@@ -3024,8 +3026,25 @@  check_for_override (tree decl, tree ctype)
       overrides_found = true;
       if (warn_override && !DECL_OVERRIDE_P (decl)
 	  && !DECL_DESTRUCTOR_P (decl))
-	warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wsuggest_override,
-		    "%qD can be marked override", decl);
+	{
+	  gcc_rich_location richloc (DECL_SOURCE_LOCATION (decl));
+	  /* Attempt to suggest adding " override" after the declarator
+	     (and before the semicolon).  */
+	  blt_node *asnode = blt_get_node_for_tree (decl);
+	  if (asnode)
+	    {
+	      /* Expect a member-declaration containing a
+		 decl-specifier-seq declarator token(;).
+		 We want the declarator.  */
+	      blt_node *declarator
+		= asnode->get_first_child_of_kind (BLT_DECLARATOR);
+	      if (declarator)
+		richloc.add_fixit_insert_after (declarator->get_finish (),
+						" override");
+	    }
+	  warning_at_rich_loc (&richloc, OPT_Wsuggest_override,
+			       "%qD can be marked override", decl);
+	}
     }
 
   if (DECL_VIRTUAL_P (decl))
diff --git a/gcc/testsuite/g++.dg/warn/Wsuggest-override.C b/gcc/testsuite/g++.dg/warn/Wsuggest-override.C
index f820f4b..8f5c133 100644
--- a/gcc/testsuite/g++.dg/warn/Wsuggest-override.C
+++ b/gcc/testsuite/g++.dg/warn/Wsuggest-override.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile }
-// { dg-options "-std=c++11 -Wsuggest-override" }
+// { dg-options "-std=c++11 -Wsuggest-override -fdiagnostics-show-caret -fblt" }
 struct A
 {
 	A();
@@ -16,8 +16,18 @@  struct B : A
 	B();
 	virtual ~B();
 	virtual void f(); // { dg-warning "can be marked override" }
+/* { dg-begin-multiline-output "" }
+  virtual void f();
+               ^
+                   override
+   { dg-end-multiline-output "" } */
 virtual int bar() override;
 int c();
 operator int();
 virtual operator float(); // { dg-warning "can be marked override" }
+/* { dg-begin-multiline-output "" }
+ virtual operator float();
+         ^~~~~~~~
+                          override
+   { dg-end-multiline-output "" } */
 };