Implement a warning diagnostic for weak vtables. Fixes PR6116.

llvm-svn: 95472
This commit is contained in:
Anders Carlsson 2010-02-06 02:27:10 +00:00
parent db2eb47835
commit 0da714a3e2
3 changed files with 35 additions and 2 deletions

View File

@ -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">;

View File

@ -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) {

View File

@ -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() { }
};
}