summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2012-09-21 03:21:07 +0000
committerDavid Blaikie <dblaikie@gmail.com>2012-09-21 03:21:07 +0000
commit348df509a0b7f21c2a274e2f928ba43bc95380d4 (patch)
tree213a46f002de0c8601c20dcf0104cd3e062ee362 /clang
parenta880186030e4626a6730917bd818ed1e50f8811f (diff)
downloadbcm5719-llvm-348df509a0b7f21c2a274e2f928ba43bc95380d4.tar.gz
bcm5719-llvm-348df509a0b7f21c2a274e2f928ba43bc95380d4.zip
PR13890: Warn on abstract final classes.
llvm-svn: 164359
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp5
-rw-r--r--clang/test/CXX/class/p2-0x.cpp8
4 files changed, 16 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 3f0093e4c3a..223c6c5e29a 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -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">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 111455a1755..0556e8adc53 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e0c655f879f..3191e3fb489 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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()) {
diff --git a/clang/test/CXX/class/p2-0x.cpp b/clang/test/CXX/class/p2-0x.cpp
index dbb01e5ad52..5b39e0ada7e 100644
--- a/clang/test/CXX/class/p2-0x.cpp
+++ b/clang/test/CXX/class/p2-0x.cpp
@@ -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'}}
+
+}
OpenPOWER on IntegriCloud