def GNUDesignator : DiagGroup<"gnu-designator">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def AbstractFinalClass : DiagGroup<"abstract-final-class">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">;
"%0 marked 'override' but does not override any member functions">;
def err_class_marked_final_used_as_base : Error<
"base %0 is marked 'final'">;
+def warn_abstract_final_class : Warning<
+ "abstract class is marked 'final'">, InGroup<AbstractFinalClass>;
// C++11 attributes
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
diag::warn_non_virtual_dtor) << Context.getRecordType(Record);
}
+ if (Record->isAbstract() && Record->hasAttr<FinalAttr>()) {
+ Diag(Record->getLocation(), diag::warn_abstract_final_class);
+ DiagnoseAbstractType(Record);
+ }
+
// See if a method overloads virtual methods in a base
/// class without overriding any.
if (!Record->isDependentType()) {
}
+namespace Test4 {
+
+struct A final { virtual void func() = 0; }; // expected-warning {{abstract class is marked 'final'}} expected-note {{unimplemented pure virtual method 'func' in 'A'}}
+struct B { virtual void func() = 0; }; // expected-note {{unimplemented pure virtual method 'func' in 'C'}}
+
+struct C final : B { }; // expected-warning {{abstract class is marked 'final'}}
+
+}