diff options
| author | Reid Kleckner <rnk@google.com> | 2016-12-06 21:44:41 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2016-12-06 21:44:41 +0000 |
| commit | b792e0694b678e08832d5cfcb52d800c6f1a01aa (patch) | |
| tree | 1eb0ef046e6b1006d07a41e632201628ab208322 /clang | |
| parent | 00cfa747156c8a7bb25be3e6a85272a61b0b15ca (diff) | |
| download | bcm5719-llvm-b792e0694b678e08832d5cfcb52d800c6f1a01aa.tar.gz bcm5719-llvm-b792e0694b678e08832d5cfcb52d800c6f1a01aa.zip | |
Disable -Wweak-vtables when there are no key functions
Our -Wweak-vtables diagnostic is powered by our key function
calculation, which checks if key functions are enabled. We won't find
any key functions in C++ ABIs that lack key functions, so -Wweak-vtables
was warning on every dynamic class before this change. So, turn off this
warning in ABIs without key functions.
Addresses PR31220
llvm-svn: 288850
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 30 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-weak-vtables.cpp | 5 |
2 files changed, 21 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6ccb3c5216b..ed77a42beba 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -14281,6 +14281,8 @@ bool Sema::DefineUsedVTables() { CXXRecordDecl *Class = VTableUses[I].first->getDefinition(); if (!Class) continue; + TemplateSpecializationKind ClassTSK = + Class->getTemplateSpecializationKind(); SourceLocation Loc = VTableUses[I].second; @@ -14304,9 +14306,8 @@ bool Sema::DefineUsedVTables() { // of an explicit instantiation declaration, suppress the // vtable; it will live with the explicit instantiation // definition. - bool IsExplicitInstantiationDeclaration - = Class->getTemplateSpecializationKind() - == TSK_ExplicitInstantiationDeclaration; + bool IsExplicitInstantiationDeclaration = + ClassTSK == TSK_ExplicitInstantiationDeclaration; for (auto R : Class->redecls()) { TemplateSpecializationKind TSK = cast<CXXRecordDecl>(R)->getTemplateSpecializationKind(); @@ -14339,17 +14340,20 @@ bool Sema::DefineUsedVTables() { if (VTablesUsed[Canonical]) Consumer.HandleVTable(Class); - // Optionally warn if we're emitting a weak vtable. - if (Class->isExternallyVisible() && - Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { + // Warn if we're emitting a weak vtable. The vtable will be weak if there is + // no key function or the key function is inlined. Don't warn in C++ ABIs + // that lack key functions, since the user won't be able to make one. + if (Context.getTargetInfo().getCXXABI().hasKeyFunctions() && + Class->isExternallyVisible() && ClassTSK != TSK_ImplicitInstantiation) { const FunctionDecl *KeyFunctionDef = nullptr; - if (!KeyFunction || - (KeyFunction->hasBody(KeyFunctionDef) && - KeyFunctionDef->isInlined())) - Diag(Class->getLocation(), Class->getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDefinition - ? diag::warn_weak_template_vtable : diag::warn_weak_vtable) - << Class; + if (!KeyFunction || (KeyFunction->hasBody(KeyFunctionDef) && + KeyFunctionDef->isInlined())) { + Diag(Class->getLocation(), + ClassTSK == TSK_ExplicitInstantiationDefinition + ? diag::warn_weak_template_vtable + : diag::warn_weak_vtable) + << Class; + } } } VTableUses.clear(); diff --git a/clang/test/SemaCXX/warn-weak-vtables.cpp b/clang/test/SemaCXX/warn-weak-vtables.cpp index d3066538715..e678f9e461e 100644 --- a/clang/test/SemaCXX/warn-weak-vtables.cpp +++ b/clang/test/SemaCXX/warn-weak-vtables.cpp @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables -// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables +// +// Check that this warning is disabled on MS ABI targets which don't have key +// functions. +// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wweak-vtables -Wweak-template-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() { } |

