<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>