forked from OSchip/llvm-project
PR13890: Warn on abstract final classes.
llvm-svn: 164359
This commit is contained in:
parent
a880186030
commit
348df509a0
|
@ -49,6 +49,7 @@ def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
|
||||||
def GNUDesignator : DiagGroup<"gnu-designator">;
|
def GNUDesignator : DiagGroup<"gnu-designator">;
|
||||||
|
|
||||||
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
|
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
|
||||||
|
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
|
||||||
|
|
||||||
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
|
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
|
||||||
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">;
|
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">;
|
||||||
|
|
|
@ -1350,6 +1350,8 @@ def err_function_marked_override_not_overriding : Error<
|
||||||
"%0 marked 'override' but does not override any member functions">;
|
"%0 marked 'override' but does not override any member functions">;
|
||||||
def err_class_marked_final_used_as_base : Error<
|
def err_class_marked_final_used_as_base : Error<
|
||||||
"base %0 is marked 'final'">;
|
"base %0 is marked 'final'">;
|
||||||
|
def warn_abstract_final_class : Warning<
|
||||||
|
"abstract class is marked 'final'">, InGroup<AbstractFinalClass>;
|
||||||
|
|
||||||
// C++11 attributes
|
// C++11 attributes
|
||||||
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
|
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
|
||||||
|
|
|
@ -3840,6 +3840,11 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
||||||
diag::warn_non_virtual_dtor) << Context.getRecordType(Record);
|
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
|
// See if a method overloads virtual methods in a base
|
||||||
/// class without overriding any.
|
/// class without overriding any.
|
||||||
if (!Record->isDependentType()) {
|
if (!Record->isDependentType()) {
|
||||||
|
|
|
@ -26,3 +26,11 @@ struct C : A<int> { }; // expected-error {{base 'A' is marked 'final'}}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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'}}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue