Hi all,

We have an enhancement request  from our users to provide 
warning if ‘override’ control is missing. This warning is off by default as it 
will
be noisy (but it will show itself with -Weverything). 
Is such a patch useful enough to go into the trunk? Also, comment on the patch 
is appreciated.
I will provide ‘fixit’ later if this is a worthwhile patch.

- Fariborz

        
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td     (revision 218382)
+++ include/clang/Basic/DiagnosticGroups.td     (working copy)
@@ -146,6 +146,8 @@
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 
+def CXX11WarnOverrideMethod : 
DiagGroup<"warn-missing-override-on-overriding-method">;
+
 // Original name of this warning in Clang
 def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td  (revision 218382)
+++ include/clang/Basic/DiagnosticSemaKinds.td  (working copy)
@@ -1683,6 +1683,9 @@
   "%select{function|functions}1">;
 def err_function_marked_override_not_overriding : Error<
   "%0 marked 'override' but does not override any member functions">;
+def warn_function_marked_not_override_overriding : Warning <
+  "%0 is not marked 'override' but overrides a member functions">,
+  InGroup<CXX11WarnOverrideMethod>, DefaultIgnore;
 def err_class_marked_final_used_as_base : Error<
   "base %0 is marked '%select{final|sealed}1'">;
 def warn_abstract_final_class : Warning<
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h   (revision 218382)
+++ include/clang/Sema/Sema.h   (working copy)
@@ -5070,6 +5070,10 @@
 
   /// CheckOverrideControl - Check C++11 override control semantics.
   void CheckOverrideControl(NamedDecl *D);
+    
+  /// DiagnoseAbsenseOfOverrideControl - Diagnose if override control was
+  /// not used in the; otherwise, overriding method.
+  void DiagnoseAbsenseOfOverrideControl(NamedDecl *D);
 
   /// CheckForFunctionMarkedFinal - Checks whether a virtual member function
   /// overrides a virtual member function marked 'final', according to
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp    (revision 218382)
+++ lib/Sema/SemaDeclCXX.cpp    (working copy)
@@ -1895,6 +1895,27 @@
       << MD->getDeclName();
 }
 
+void Sema::DiagnoseAbsenseOfOverrideControl(NamedDecl *D) {
+  if (D->isInvalidDecl())
+    return;
+  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
+  if (!MD || 
Diags.isIgnored(diag::warn_function_marked_not_override_overriding,
+                             MD->getLocation()))
+    return;
+  bool HasOverriddenMethods =
+    MD->begin_overridden_methods() != MD->end_overridden_methods();
+  if (HasOverriddenMethods) {
+    Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)
+      << MD->getDeclName();
+    for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
+         E = MD->end_overridden_methods(); I != E; ++I) {
+      const CXXMethodDecl *OMD = *I;
+      Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+      break;
+    }
+  }
+}
+
 /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member
 /// function overrides a virtual member function marked 'final', according to
 /// C++11 [class.virtual]p4.
@@ -2182,6 +2203,9 @@
 
   CheckOverrideControl(Member);
 
+  if (LangOpts.CPlusPlus11 && !Member->hasAttr<OverrideAttr>())
+    DiagnoseAbsenseOfOverrideControl(Member);
+
   assert((Name || isInstField) && "No identifier for non-field ?");
 
   if (isInstField) {
Index: test/SemaCXX/cxx11-warn-missing-override.cpp
===================================================================
--- test/SemaCXX/cxx11-warn-missing-override.cpp        (revision 0)
+++ test/SemaCXX/cxx11-warn-missing-override.cpp        (working copy)
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions 
-Wwarn-missing-override-on-overriding-method -verify -std=c++11 %s
+// rdar://18295240
+
+struct A
+{
+    virtual void foo(); // expected-note {{overridden virtual function is 
here}}
+    void bar();
+    virtual void gorf() {} // expected-note {{overridden virtual function is 
here}}
+    virtual void g() = 0; // expected-note {{overridden virtual function is 
here}}
+};
+
+struct B : A
+{
+    void foo(); // expected-warning {{'foo' is not marked 'override' but 
overrides a member functions}}
+    void bar();
+};
+
+struct C : B
+{
+    virtual void gorf() {} // expected-warning {{'gorf' is not marked 
'override' but overrides a member functions}}
+    virtual void g() = 0; // expected-warning {{'g' is not marked 'override' 
but overrides a member functions}}
+};
Index: test/SemaCXX/virtuals.cpp
===================================================================
--- test/SemaCXX/virtuals.cpp   (revision 218382)
+++ test/SemaCXX/virtuals.cpp   (working copy)
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions 
-Wwarn-missing-override-on-overriding-method -verify -std=c++11 %s
 
 class A {
   virtual void f();
-  virtual void g() = 0; // expected-note{{unimplemented pure virtual method 
'g' in 'A'}}
+  virtual void g() = 0; // expected-note{{unimplemented pure virtual method 
'g' in 'A'}} \
+                       // expected-note {{overridden virtual function is here}}
 
   void h() = 0; // expected-error {{'h' is not virtual and cannot be declared 
pure}}
   void i() = 1; // expected-error {{initializer on function does not look like 
a pure-specifier}}
@@ -19,7 +20,7 @@
 
 class B : public A {
   // Needs to recognize that overridden function is virtual.
-  void g() = 0;
+  void g() = 0; // expected-warning {{'g' is not marked 'override' but 
overrides a member functions}}
 
   // Needs to recognize that function does not override.
   void g(int) = 0; // expected-error{{'g' is not virtual and cannot be 
declared pure}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to