diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-06 02:27:10 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-06 02:27:10 +0000 |
commit | 1610b8198e31eb6d77d4d6904d6af88ef5cc6d3b (patch) | |
tree | d7a89af94a198c316658b447c24486c455eb2026 | |
parent | 68b6b87b6beb7922fc2c8ab923ba2ce125490363 (diff) |
Implement a warning diagnostic for weak vtables. Fixes PR6116.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95472 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 11 | ||||
-rw-r--r-- | test/SemaCXX/warn-weak-vtables.cpp | 21 |
3 files changed, 35 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index cecd757a65..d31dbd531a 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -390,6 +390,11 @@ def err_deleted_non_function : Error< def err_deleted_decl_not_first : Error< "deleted definition must be first declaration">; +def warn_weak_vtable : Warning< + "%0 has no out-of-line virtual method definitions; its vtable will be " + "emitted in every translation unit">, + InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore; + // C++ exception specifications def err_exception_spec_in_typedef : Error< "exception specifications are not allowed in typedefs">; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 52fc9b74e0..659969334e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5002,9 +5002,16 @@ RecordDynamicClassesWithNoKeyFunction(Sema &S, CXXRecordDecl *Record, if (Record->isDependentContext() || !Record->isDefinition()) return; - if (Record->isDynamicClass() && !S.Context.getKeyFunction(Record)) - S.ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(Record, Loc)); + if (Record->isDynamicClass()) { + const CXXMethodDecl *KeyFunction = S.Context.getKeyFunction(Record); + if (!KeyFunction) + S.ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(Record, Loc)); + + if ((!KeyFunction || KeyFunction->getBody() && KeyFunction->isInlined()) && + Record->getLinkage() == ExternalLinkage) + S.Diag(Record->getLocation(), diag::warn_weak_vtable) << Record; + } for (DeclContext::decl_iterator D = Record->decls_begin(), DEnd = Record->decls_end(); D != DEnd; ++D) { diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp new file mode 100644 index 0000000000..1ea88a548e --- /dev/null +++ b/test/SemaCXX/warn-weak-vtables.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables + +struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}} + virtual void f() { } +}; + +template<typename T> struct B { + virtual void f() { } +}; + +namespace { + struct C { + virtual void f() { } + }; +} + +void f() { + struct A { + virtual void f() { } + }; +}
\ No newline at end of file |