From 9f08834e0f4e47129892c07ab8535653934b3b97 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 24 Mar 2014 23:54:09 +0000 Subject: [PATCH] Fix a bug where an explicit instantiation declaration of a class template specialization would make us think it might have a key function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204686 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/RecordLayoutBuilder.cpp | 3 ++- test/CodeGenCXX/template-instantiation.cpp | 24 +++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 0c21bde382..ce55d2e49a 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1957,10 +1957,11 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context, if (!RD->isExternallyVisible()) return 0; - // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6. + // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6. // Same behavior as GCC. TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); if (TSK == TSK_ImplicitInstantiation || + TSK == TSK_ExplicitInstantiationDeclaration || TSK == TSK_ExplicitInstantiationDefinition) return 0; diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp index 80283a1edd..3baa946b0b 100644 --- a/test/CodeGenCXX/template-instantiation.cpp +++ b/test/CodeGenCXX/template-instantiation.cpp @@ -5,11 +5,15 @@ // // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE -// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant +// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE +// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE +// CHECK: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant // CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32] // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A +// CHECK: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant + // CHECK-NOT: _ZTVN5test31SIiEE // CHECK-NOT: _ZTSN5test31SIiEE @@ -39,11 +43,21 @@ namespace test0 { virtual void xsgetn(); }; - // This specialization should cause the vtable to be emitted, even with - // the following extern template declaration. - template<> void stdio_sync_filebuf::xsgetn() { + // This specialization is not a key function, so doesn't cause the vtable to + // be instantiated unless we're instantiating a class definition anyway. + template<> void stdio_sync_filebuf::xsgetn() { + } + template<> void stdio_sync_filebuf::xsgetn() { + } + template<> void stdio_sync_filebuf::xsgetn() { } - extern template class stdio_sync_filebuf; + template<> void stdio_sync_filebuf::xsgetn() { + } + extern template class stdio_sync_filebuf; + + // These two both cause vtables to be emitted. + template class stdio_sync_filebuf; + stdio_sync_filebuf implicit_instantiation; } namespace test1 { -- 2.40.0