@@ -1897,6 +1897,31 @@ void Sema::CheckOverrideControl(NamedDecl *D) {
1897
1897
<< MD->getDeclName();
1898
1898
}
1899
1899
1900
+ void Sema::DiagnoseAbsenseOfOverrideControl(NamedDecl *D) {
1901
+ if (D->isInvalidDecl())
1902
+ return;
1903
+ CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
1904
+ if (!MD || MD->isImplicit() || isa<CXXDestructorDecl>(MD))
1905
+ return;
1906
+
1907
+ bool HasOverriddenMethods =
1908
+ MD->begin_overridden_methods() != MD->end_overridden_methods();
1909
+ if (HasOverriddenMethods) {
1910
+ SourceLocation EndLocation =
1911
+ (MD->isPure() || MD->hasAttr<FinalAttr>())
1912
+ ? SourceLocation() : MD->getSourceRange().getEnd();
1913
+ Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)
1914
+ << MD->getDeclName()
1915
+ << FixItHint::CreateReplacement(EndLocation, ") override");
1916
+ for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
1917
+ E = MD->end_overridden_methods(); I != E; ++I) {
1918
+ const CXXMethodDecl *OMD = *I;
1919
+ Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
1920
+ break;
1921
+ }
1922
+ }
1923
+ }
1924
+
1900
1925
/// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member
1901
1926
/// function overrides a virtual member function marked 'final', according to
1902
1927
/// C++11 [class.virtual]p4.
@@ -4680,13 +4705,18 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
4680
4705
}
4681
4706
}
4682
4707
4708
+ bool HasMethodWithOverrideControl = false,
4709
+ HasOverridingMethodWithoutOverrideControl = false;
4683
4710
if (!Record->isDependentType()) {
4684
4711
for (auto *M : Record->methods()) {
4685
4712
// See if a method overloads virtual methods in a base
4686
4713
// class without overriding any.
4687
4714
if (!M->isStatic())
4688
4715
DiagnoseHiddenVirtualMethods(M);
4689
-
4716
+ if (M->hasAttr<OverrideAttr>())
4717
+ HasMethodWithOverrideControl = true;
4718
+ else if (M->begin_overridden_methods() != M->end_overridden_methods())
4719
+ HasOverridingMethodWithoutOverrideControl = true;
4690
4720
// Check whether the explicitly-defaulted special members are valid.
4691
4721
if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
4692
4722
CheckExplicitlyDefaultedSpecialMember(M);
@@ -4705,6 +4735,14 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
4705
4735
}
4706
4736
}
4707
4737
4738
+ if (HasMethodWithOverrideControl
4739
+ && HasOverridingMethodWithoutOverrideControl) {
4740
+ // At least one method has the 'override' control declared.
4741
+ // Diagnose all other overridden methods which do not have 'override' specified on them.
4742
+ for (auto *M : Record->methods())
4743
+ if (!M->hasAttr<OverrideAttr>())
4744
+ DiagnoseAbsenseOfOverrideControl(M);
4745
+ }
4708
4746
// C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member
4709
4747
// function that is not a constructor declares that member function to be
4710
4748
// const. [...] The class of which that function is a member shall be
0 commit comments