<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div><br><div><div>On Oct 2, 2014, at 5:24 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 2, 2014 at 4:13 PM, Fariborz Jahanian <span dir="ltr"><<a href="mailto:fjahanian@apple.com" target="_blank">fjahanian@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: fjahanian<br>
Date: Thu Oct  2 18:13:51 2014<br>
New Revision: 218925<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=218925&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=218925&view=rev</a><br>
Log:<br>
Patch to warn if 'override' is missing<br>
for an overriding method if class has at least one<br>
'override' specified on one of its methods.<br>
Reviewed by Doug Gregor. <a href="rdar://18295240">rdar://18295240</a><br>
(I have already checked in all llvm files with missing 'override'<br>
 methods and Bob Wilson has fixed a TableGen of FastISel so<br>
 no warnings are expected from build of llvm after this patch.<br>
 I have already verified this).<br>
<br>
Added:<br>
    cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp<br>
    cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp<br>
    cfe/trunk/test/FixIt/fixit-cxx0x.cpp<br>
    cfe/trunk/test/Parser/MicrosoftExtensions.cpp<br>
    cfe/trunk/test/Parser/cxx0x-decl.cpp<br>
    cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp<br>
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp<br>
    cfe/trunk/test/SemaCXX/attr-gnu.cpp<br>
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp<br>
    cfe/trunk/test/SemaCXX/ms-interface.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Oct  2 18:13:51 2014<br>
@@ -146,6 +146,8 @@ def CXX98CompatPedantic : DiagGroup<"c++<br>
<br>
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;<br>
<br>
+def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;<br>
+<br>
 // Original name of this warning in Clang<br>
 def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Oct  2 18:13:51 2014<br>
@@ -1689,6 +1689,9 @@ def override_keyword_hides_virtual_membe<br>
   "%select{function|functions}1">;<br>
 def err_function_marked_override_not_overriding : Error<<br>
   "%0 marked 'override' but does not override any member functions">;<br>
+def warn_function_marked_not_override_overriding : Warning <<br>
+  "%0 overrides a member function but is not marked 'override'">,<br>
+  InGroup<CXX11WarnOverrideMethod>;<br>
 def err_class_marked_final_used_as_base : Error<<br>
   "base %0 is marked '%select{final|sealed}1'">;<br>
 def warn_abstract_final_class : Warning<<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct  2 18:13:51 2014<br>
@@ -5084,6 +5084,10 @@ public:<br>
<br>
   /// CheckOverrideControl - Check C++11 override control semantics.<br>
   void CheckOverrideControl(NamedDecl *D);<br>
+<br>
+  /// DiagnoseAbsenseOfOverrideControl - Diagnose if override control was<br>
+  /// not used in the; otherwise, overriding method.<br></blockquote><div><br></div><div>Something weird has happened to this comment.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  void DiagnoseAbsenseOfOverrideControl(NamedDecl *D);<br>
<br>
   /// CheckForFunctionMarkedFinal - Checks whether a virtual member function<br>
   /// overrides a virtual member function marked 'final', according to<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Oct  2 18:13:51 2014<br>
@@ -1897,6 +1897,31 @@ void Sema::CheckOverrideControl(NamedDec<br>
       << MD->getDeclName();<br>
 }<br>
<br>
+void Sema::DiagnoseAbsenseOfOverrideControl(NamedDecl *D) {<br>
+  if (D->isInvalidDecl())<br>
+    return;<br>
+  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);<br>
+  if (!MD || MD->isImplicit() || isa<CXXDestructorDecl>(MD))<br>
+    return;<br></blockquote><div><br></div><div>Why do you skip destructors?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+  bool HasOverriddenMethods =<br>
+    MD->begin_overridden_methods() != MD->end_overridden_methods();<br>
+  if (HasOverriddenMethods) {<br>
+    SourceLocation EndLocation =<br>
+      (MD->isPure() || MD->hasAttr<FinalAttr>())<br></blockquote><div><br></div><div>We should not warn if the function (or the class) has the 'final' attribute.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        ? SourceLocation() : MD->getSourceRange().getEnd();<br>
+    Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)<br>
+      << MD->getDeclName()<br>
+      << FixItHint::CreateReplacement(EndLocation, ") override");<br></blockquote><div><br></div><div>This fixit is not correct. The EndLocation isn't necessarily the location of the `)`, and the `override` does not necessarily go after the `)`. (Consider cv-qualifiers and ref-qualifiers, or functions whose return type includes trailing declarator chunks, or functions with trailing return types.)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),<br>
+         E = MD->end_overridden_methods(); I != E; ++I) {<br>
+      const CXXMethodDecl *OMD = *I;<br>
+      Diag(OMD->getLocation(), diag::note_overridden_virtual_function);<br>
+      break;<br>
+    }<br>
+  }<br>
+}<br>
+<br>
 /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member<br>
 /// function overrides a virtual member function marked 'final', according to<br>
 /// C++11 [class.virtual]p4.<br>
@@ -4680,13 +4705,18 @@ void Sema::CheckCompletedCXXClass(CXXRec<br>
     }<br>
   }<br>
<br>
+  bool HasMethodWithOverrideControl = false,<br>
+       HasOverridingMethodWithoutOverrideControl = false;<br>
   if (!Record->isDependentType()) {<br>
     for (auto *M : Record->methods()) {<br>
       // See if a method overloads virtual methods in a base<br>
       // class without overriding any.<br>
       if (!M->isStatic())<br>
         DiagnoseHiddenVirtualMethods(M);<br>
-<br>
+      if (M->hasAttr<OverrideAttr>())<br>
+        HasMethodWithOverrideControl = true;<br>
+      else if (M->begin_overridden_methods() != M->end_overridden_methods())<br></blockquote><div><br></div><div>Maybe just use M->size_overridden_methods() here.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        HasOverridingMethodWithoutOverrideControl = true;<br>
       // Check whether the explicitly-defaulted special members are valid.<br>
       if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())<br>
         CheckExplicitlyDefaultedSpecialMember(M);<br>
@@ -4705,6 +4735,14 @@ void Sema::CheckCompletedCXXClass(CXXRec<br>
     }<br>
   }<br>
<br>
+  if (HasMethodWithOverrideControl<br>
+      && HasOverridingMethodWithoutOverrideControl) {<br>
+    // At least one method has the 'override' control declared.<br>
+    // Diagnose all other overridden methods which do not have 'override' specified on them.<br>
+    for (auto *M : Record->methods())<br>
+      if (!M->hasAttr<OverrideAttr>())<br>
+        DiagnoseAbsenseOfOverrideControl(M);<br>
+  }<br>
   // C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member<br>
   // function that is not a constructor declares that member function to be<br>
   // const. [...] The class of which that function is a member shall be<br>
<br>
Modified: cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/class.derived/class.virtual/p3-0x.cpp Thu Oct  2 18:13:51 2014<br>
@@ -61,7 +61,7 @@ struct D : B {<br>
 namespace PR13499 {<br>
   struct X {<br>
     virtual void f();<br>
-    virtual void h();<br>
+    virtual void h(); // expected-note 2 {{overridden virtual function is here}}<br>
   };<br>
   template<typename T> struct A : X {<br>
     void f() override;<br>
@@ -83,7 +83,7 @@ namespace PR13499 {<br>
   template<typename...T> struct E : X {<br>
     void f(T...) override;<br>
     void g(T...) override; // expected-error {{only virtual member functions can be marked 'override'}}<br>
-    void h(T...) final;<br>
+    void h(T...) final; // expected-warning {{'h' overrides a member function but is not marked 'override'}}<br></blockquote><div><br></div><div>This warning is bogus; it makes no sense to require both 'override' and 'final'.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     void i(T...) final; // expected-error {{only virtual member functions can be marked 'final'}}<br>
   };<br>
   // FIXME: Diagnose these in the template definition, not in the instantiation.<br>
@@ -91,13 +91,13 @@ namespace PR13499 {<br>
<br>
   template<typename T> struct Y : T {<br>
     void f() override;<br>
-    void h() final;<br>
+    void h() final; // expected-warning {{'h' overrides a member function but is not marked 'override'}}<br></blockquote><div><br></div><div>... likewise.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   };<br>
   template<typename T> struct Z : T {<br>
     void g() override; // expected-error {{only virtual member functions can be marked 'override'}}<br>
     void i() final; // expected-error {{only virtual member functions can be marked 'final'}}<br>
   };<br>
-  Y<X> y;<br>
+  Y<X> y; // expected-note {{in instantiation of}}<br>
   Z<X> z; // expected-note {{in instantiation of}}<br>
 }<br>
<br>
<br>
Added: cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp?rev=218925&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp?rev=218925&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp (added)<br>
+++ cfe/trunk/test/FixIt/cxx11-fixit-missing-override.cpp Thu Oct  2 18:13:51 2014<br>
@@ -0,0 +1,33 @@<br>
+// RUN: cp %s %t<br>
+// RUN: %clang_cc1 -x c++ -std=c++11 -Winconsistent-missing-override -fixit %t<br>
+// RUN: %clang_cc1 -x c++ -std=c++11 -Winconsistent-missing-override -Werror %t<br>
+<br>
+struct A<br>
+{<br>
+    virtual void foo();<br>
+    virtual void bar(); // expected-note {{overridden virtual function is here}}<br>
+    virtual void gorf() {}<br>
+    virtual void g() = 0; // expected-note {{overridden virtual function is here}}<br>
+};<br>
+<br>
+struct B : A<br>
+{<br>
+    void foo() override;<br>
+    void bar(); // expected-warning {{'bar' overrides a member function but is not marked 'override'}}<br>
+};<br>
+<br>
+struct C : B<br>
+{<br>
+    virtual void g() override = 0;  // expected-warning {{'g' overrides a member function but is not marked 'override'}}<br>
+    virtual void gorf() override {}<br>
+    void foo() {}<br>
+};<br>
+<br>
+struct D : C {<br>
+  virtual void g()override ;<br>
+  virtual void foo(){<br>
+  }<br>
+  void bar() override;<br>
+};<br>
+<br>
+<br>
<br>
Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)<br>
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Thu Oct  2 18:13:51 2014<br>
@@ -24,7 +24,7 @@ namespace SemiCommaTypo {<br>
   int o;<br>
<br>
   struct Base {<br>
-    virtual void f2(), f3();<br>
+    virtual void f2(), f3(); // expected-note {{overridden virtual function is here}}<br>
   };<br>
   struct MemberDeclarator : Base {<br>
     int k : 4,<br>
@@ -33,7 +33,7 @@ namespace SemiCommaTypo {<br>
     char c, // expected-error {{expected ';' at end of declaration}}<br>
     typedef void F(), // expected-error {{expected ';' at end of declaration}}<br>
     F f1,<br>
-      f2 final,<br>
+      f2 final, // expected-warning {{'f2' overrides a member function but is not marked 'override'}}<br>
       f3 override, // expected-error {{expected ';' at end of declaration}}<br>
   };<br>
 }<br>
<br>
Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)<br>
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Thu Oct  2 18:13:51 2014<br>
@@ -208,12 +208,12 @@ extern TypenameWrongPlace<AAAA> PR16925;<br>
<br>
 __interface MicrosoftInterface;<br>
 __interface MicrosoftInterface {<br>
-   void foo1() = 0;<br>
+   void foo1() = 0; // expected-note {{overridden virtual function is here}}<br>
    virtual void foo2() = 0;<br>
 };<br>
<br>
 __interface MicrosoftDerivedInterface : public MicrosoftInterface {<br>
-  void foo1();<br>
+  void foo1(); // expected-warning {{'foo1' overrides a member function but is not marked 'override'}}<br>
   void foo2() override;<br>
   void foo3();<br>
 };<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-decl.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-decl.cpp Thu Oct  2 18:13:51 2014<br>
@@ -83,13 +83,13 @@ namespace PR5066 {<br>
<br>
 namespace FinalOverride {<br>
   struct Base {<br>
-    virtual void *f();<br>
+    virtual void *f(); // expected-note {{overridden virtual function is here}}<br>
     virtual void *g();<br>
     virtual void *h();<br>
     virtual void *i();<br>
   };<br>
   struct Derived : Base {<br>
-    virtual auto f() -> void *final;<br>
+    virtual auto f() -> void *final; // expected-warning {{'f' overrides a member function but is not marked 'override'}}<br>
     virtual auto g() -> void *override;<br>
     virtual auto h() -> void *final override;<br>
     virtual auto i() -> void *override final;<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-in-cxx98.cpp Thu Oct  2 18:13:51 2014<br>
@@ -10,11 +10,12 @@ struct X {<br>
<br>
 struct B {<br>
   virtual void f();<br>
-  virtual void g();<br>
+  virtual void g(); // expected-note {{overridden virtual function is here}}<br>
 };<br>
 struct D final : B { // expected-warning {{'final' keyword is a C++11 extension}}<br>
   virtual void f() override; // expected-warning {{'override' keyword is a C++11 extension}}<br>
-  virtual void g() final; // expected-warning {{'final' keyword is a C++11 extension}}<br>
+  virtual void g() final; // expected-warning {{'final' keyword is a C++11 extension}} \<br>
+                         // expected-warning {{'g' overrides a member function but is not marked 'override'}}<br>
 };<br>
<br>
 void NewBracedInitList() {<br>
<br>
Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Thu Oct  2 18:13:51 2014<br>
@@ -372,14 +372,14 @@ struct SomeBase {<br>
<br>
   // expected-note@+2 {{overridden virtual function is here}}<br>
   // expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}<br>
-  virtual void SealedFunction() sealed;<br>
+  virtual void SealedFunction() sealed; // expected-note {{overridden virtual function is here}}<br>
 };<br>
<br>
 // expected-note@+2 {{'SealedType' declared here}}<br>
 // expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}<br>
 struct SealedType sealed : SomeBase {<br>
   // expected-error@+1 {{declaration of 'SealedFunction' overrides a 'sealed' function}}<br>
-  virtual void SealedFunction();<br>
+  virtual void SealedFunction(); // expected-warning {{'SealedFunction' overrides a member function but is not marked 'override'}}<br>
<br>
   // expected-warning@+1 {{'override' keyword is a C++11 extension}}<br>
   virtual void OverrideMe() override;<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-gnu.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-gnu.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-gnu.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/attr-gnu.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-gnu.cpp Thu Oct  2 18:13:51 2014<br>
@@ -15,14 +15,15 @@ void g(int a[static [[]] 5]); // expecte<br>
 namespace {<br>
 class B {<br>
 public:<br>
-  virtual void test() {}<br>
+  virtual void test() {} // expected-note {{overridden virtual function is here}}<br>
   virtual void test2() {}<br>
   virtual void test3() {}<br>
 };<br>
<br>
 class D : public B {<br>
 public:<br>
-  void test() __attribute__((deprecated)) final {} // expected-warning {{GCC does not allow an attribute in this position on a function declaration}}<br>
+  void test() __attribute__((deprecated)) final {} // expected-warning {{GCC does not allow an attribute in this position on a function declaration}} \<br>
+                                                  // expected-warning {{'test' overrides a member function but is not marked 'override'}}<br>
   void test2() [[]] override {} // Ok<br>
   void test3() __attribute__((cf_unknown_transfer)) override {} // Ok, not known to GCC.<br>
 };<br>
<br>
Added: cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp?rev=218925&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp?rev=218925&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/cxx11-warn-missing-override.cpp Thu Oct  2 18:13:51 2014<br>
@@ -0,0 +1,21 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -Winconsistent-missing-override -verify -std=c++11 %s<br>
+struct A<br>
+{<br>
+    virtual void foo();<br>
+    virtual void bar(); // expected-note {{overridden virtual function is here}}<br>
+    virtual void gorf() {}<br>
+    virtual void g() = 0; // expected-note {{overridden virtual function is here}}<br>
+};<br>
+<br>
+struct B : A<br>
+{<br>
+    void foo() override;<br>
+    void bar(); // expected-warning {{'bar' overrides a member function but is not marked 'override'}}<br>
+};<br>
+<br>
+struct C : B<br>
+{<br>
+    virtual void g() = 0;  // expected-warning {{'g' overrides a member function but is not marked 'override'}}<br>
+    virtual void gorf() override {}<br>
+};<br>
+<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Thu Oct  2 18:13:51 2014<br>
@@ -120,11 +120,12 @@ struct InClassInit {<br>
<br>
 struct OverrideControlBase {<br>
   virtual void f();<br>
-  virtual void g();<br>
+  virtual void g(); // expected-note {{overridden virtual function is here}}<br>
 };<br>
 struct OverrideControl final : OverrideControlBase { // expected-warning {{'final' keyword is incompatible with C++98}}<br>
   virtual void f() override; // expected-warning {{'override' keyword is incompatible with C++98}}<br>
-  virtual void g() final; // expected-warning {{'final' keyword is incompatible with C++98}}<br>
+  virtual void g() final; // expected-warning {{'final' keyword is incompatible with C++98}} \<br>
+                         // expected-warning {{'g' overrides a member function but is not marked 'override'}}<br>
 };<br>
<br>
 using AliasDecl = int; // expected-warning {{alias declarations are incompatible with C++98}}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/ms-interface.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ms-interface.cpp?rev=218925&r1=218924&r2=218925&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ms-interface.cpp?rev=218925&r1=218924&r2=218925&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/ms-interface.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/ms-interface.cpp Thu Oct  2 18:13:51 2014<br>
@@ -12,7 +12,7 @@ __interface I1 {<br>
   operator int();<br>
   // expected-error@+1 {{nested class I1::(anonymous) is not permitted within an interface type}}<br>
   struct { int a; };<br>
-  void fn2() {<br>
+  void fn2() { // expected-note {{overridden virtual function is here}}<br>
     struct A { }; // should be ignored: not a nested class<br>
   }<br>
 protected: // expected-error {{interface types cannot specify 'protected' access}}<br>
@@ -44,7 +44,7 @@ __interface I3 final {<br>
 __interface I4 : I1, I2 {<br>
   void fn1() const override;<br>
   // expected-error@+1 {{'final' keyword not permitted with interface types}}<br>
-  void fn2() final;<br>
+  void fn2() final; // expected-warning {{'fn2' overrides a member function but is not marked 'override'}}<br>
 };<br>
<br>
 // expected-error@+1 {{interface type cannot inherit from non-public 'interface I1'}}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>
</blockquote></div><br></div></body></html>