]> granicus.if.org Git - clang/commitdiff
PR13890: Warn on abstract final classes.
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 21 Sep 2012 03:21:07 +0000 (03:21 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 21 Sep 2012 03:21:07 +0000 (03:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164359 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp
test/CXX/class/p2-0x.cpp

index 3f0093e4c3a0c99b09cb2d91d4508765391a5421..223c6c5e29ad82e0191d4ae595c71ac696b50076 100644 (file)
@@ -49,6 +49,7 @@ def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
 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">;
index 111455a1755ab74b393d226611f98ec565b69f89..0556e8adc534d0e5aead511ff32aae7e5aa0f861 100644 (file)
@@ -1350,6 +1350,8 @@ def err_function_marked_override_not_overriding : Error<
   "%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">;
index e0c655f879f386b62cddaaca191af92bb4441dad..3191e3fb489018d3ac5f87d98490c8941b2a0f82 100644 (file)
@@ -3840,6 +3840,11 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *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
   /// class without overriding any.
   if (!Record->isDependentType()) {
index dbb01e5ad5285cca07d11e0a217aabc081ff3022..5b39e0ada7e2cf36c07f63fbc22d393e0c1d985b 100644 (file)
@@ -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'}}
+
+}