summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-10-02 23:13:51 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-10-02 23:13:51 +0000
commitb91c5d6a79665c9028f15669dc41b5973b9fd8f8 (patch)
tree10280a0264c8f5e06807e0dd2f2e1f6495886d34 /clang/lib/Sema
parenta3f58694b5c0fa2af552d70220da787dc6d7e890 (diff)
downloadbcm5719-llvm-b91c5d6a79665c9028f15669dc41b5973b9fd8f8.tar.gz
bcm5719-llvm-b91c5d6a79665c9028f15669dc41b5973b9fd8f8.zip
Patch to warn if 'override' is missing
for an overriding method if class has at least one 'override' specified on one of its methods. Reviewed by Doug Gregor. rdar://18295240 (I have already checked in all llvm files with missing 'override' methods and Bob Wilson has fixed a TableGen of FastISel so no warnings are expected from build of llvm after this patch. I have already verified this). llvm-svn: 218925
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ed15012a160..ef451a97997 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1897,6 +1897,31 @@ void Sema::CheckOverrideControl(NamedDecl *D) {
<< MD->getDeclName();
}
+void Sema::DiagnoseAbsenseOfOverrideControl(NamedDecl *D) {
+ if (D->isInvalidDecl())
+ return;
+ CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
+ if (!MD || MD->isImplicit() || isa<CXXDestructorDecl>(MD))
+ return;
+
+ bool HasOverriddenMethods =
+ MD->begin_overridden_methods() != MD->end_overridden_methods();
+ if (HasOverriddenMethods) {
+ SourceLocation EndLocation =
+ (MD->isPure() || MD->hasAttr<FinalAttr>())
+ ? SourceLocation() : MD->getSourceRange().getEnd();
+ Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)
+ << MD->getDeclName()
+ << FixItHint::CreateReplacement(EndLocation, ") override");
+ 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.
@@ -4680,13 +4705,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->begin_overridden_methods() != M->end_overridden_methods())
+ HasOverridingMethodWithoutOverrideControl = true;
// Check whether the explicitly-defaulted special members are valid.
if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
CheckExplicitlyDefaultedSpecialMember(M);
@@ -4705,6 +4735,14 @@ 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())
+ if (!M->hasAttr<OverrideAttr>())
+ DiagnoseAbsenseOfOverrideControl(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
OpenPOWER on IntegriCloud