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, 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(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()) + 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}}