mirror of https://github.com/microsoft/clang.git
c++11 patch to issue warning on missing 'override' on
overriding methods. Patch review by Richard Smith. rdar://18295240 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220703 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
627380e9f7
commit
3b10ac09cf
|
@ -147,6 +147,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
|
|||
|
||||
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
|
||||
|
||||
def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
|
||||
|
||||
// Original name of this warning in Clang
|
||||
def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
|
||||
|
||||
|
|
|
@ -1691,6 +1691,9 @@ def override_keyword_hides_virtual_member_function : Error<
|
|||
"%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 overrides a member function but is not marked 'override'">,
|
||||
InGroup<CXX11WarnOverrideMethod>;
|
||||
def err_class_marked_final_used_as_base : Error<
|
||||
"base %0 is marked '%select{final|sealed}1'">;
|
||||
def warn_abstract_final_class : Warning<
|
||||
|
|
|
@ -5139,6 +5139,10 @@ public:
|
|||
/// CheckOverrideControl - Check C++11 override control semantics.
|
||||
void CheckOverrideControl(NamedDecl *D);
|
||||
|
||||
/// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
|
||||
/// not used in the declaration of an overriding method.
|
||||
void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
|
||||
|
||||
/// CheckForFunctionMarkedFinal - Checks whether a virtual member function
|
||||
/// overrides a virtual member function marked 'final', according to
|
||||
/// C++11 [class.virtual]p4.
|
||||
|
|
|
@ -1897,6 +1897,22 @@ void Sema::CheckOverrideControl(NamedDecl *D) {
|
|||
<< MD->getDeclName();
|
||||
}
|
||||
|
||||
void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
|
||||
if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>())
|
||||
return;
|
||||
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
|
||||
if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>() ||
|
||||
isa<CXXDestructorDecl>(MD))
|
||||
return;
|
||||
|
||||
if (MD->size_overridden_methods() > 0) {
|
||||
Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)
|
||||
<< MD->getDeclName();
|
||||
const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
|
||||
Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
|
||||
}
|
||||
}
|
||||
|
||||
/// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member
|
||||
/// function overrides a virtual member function marked 'final', according to
|
||||
/// C++11 [class.virtual]p4.
|
||||
|
@ -4763,13 +4779,18 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
|||
}
|
||||
}
|
||||
|
||||
bool HasMethodWithOverrideControl = false,
|
||||
HasOverridingMethodWithoutOverrideControl = false;
|
||||
if (!Record->isDependentType()) {
|
||||
for (auto *M : Record->methods()) {
|
||||
// See if a method overloads virtual methods in a base
|
||||
// class without overriding any.
|
||||
if (!M->isStatic())
|
||||
DiagnoseHiddenVirtualMethods(M);
|
||||
|
||||
if (M->hasAttr<OverrideAttr>())
|
||||
HasMethodWithOverrideControl = true;
|
||||
else if (M->size_overridden_methods() > 0)
|
||||
HasOverridingMethodWithoutOverrideControl = true;
|
||||
// Check whether the explicitly-defaulted special members are valid.
|
||||
if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
|
||||
CheckExplicitlyDefaultedSpecialMember(M);
|
||||
|
@ -4788,6 +4809,13 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
|||
}
|
||||
}
|
||||
|
||||
if (HasMethodWithOverrideControl &&
|
||||
HasOverridingMethodWithoutOverrideControl) {
|
||||
// At least one method has the 'override' control declared.
|
||||
// Diagnose all other overridden methods which do not have 'override' specified on them.
|
||||
for (auto *M : Record->methods())
|
||||
DiagnoseAbsenceOfOverrideControl(M);
|
||||
}
|
||||
// C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member
|
||||
// function that is not a constructor declares that member function to be
|
||||
// const. [...] The class of which that function is a member shall be
|
||||
|
|
|
@ -208,12 +208,12 @@ extern TypenameWrongPlace<AAAA> PR16925;
|
|||
|
||||
__interface MicrosoftInterface;
|
||||
__interface MicrosoftInterface {
|
||||
void foo1() = 0;
|
||||
void foo1() = 0; // expected-note {{overridden virtual function is here}}
|
||||
virtual void foo2() = 0;
|
||||
};
|
||||
|
||||
__interface MicrosoftDerivedInterface : public MicrosoftInterface {
|
||||
void foo1();
|
||||
void foo1(); // expected-warning {{'foo1' overrides a member function but is not marked 'override'}}
|
||||
void foo2() override;
|
||||
void foo3();
|
||||
};
|
||||
|
|
|
@ -372,14 +372,15 @@ struct SomeBase {
|
|||
|
||||
// expected-note@+2 {{overridden virtual function is here}}
|
||||
// expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}
|
||||
virtual void SealedFunction() sealed;
|
||||
virtual void SealedFunction() sealed; // expected-note {{overridden virtual function is here}}
|
||||
};
|
||||
|
||||
// expected-note@+2 {{'SealedType' declared here}}
|
||||
// expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}
|
||||
struct SealedType sealed : SomeBase {
|
||||
// expected-error@+1 {{declaration of 'SealedFunction' overrides a 'sealed' function}}
|
||||
virtual void SealedFunction();
|
||||
// expected-error@+2 {{declaration of 'SealedFunction' overrides a 'sealed' function}}
|
||||
// FIXME. warning can be suppressed if we're also issuing error for overriding a 'final' function.
|
||||
virtual void SealedFunction(); // expected-warning {{'SealedFunction' overrides a member function but is not marked 'override'}}
|
||||
|
||||
// expected-warning@+1 {{'override' keyword is a C++11 extension}}
|
||||
virtual void OverrideMe() override;
|
||||
|
|
Loading…
Reference in New Issue