From b51a70396e5d99bec354085f7cf96d127988f37b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 14 Sep 2018 15:18:30 +0000 Subject: [PATCH] [clang-cl] Fix PR38934: failing to dllexport class template member w/ explicit instantiation and PCH The code in ASTContext::DeclMustBeEmitted was supposed to handle this, but didn't take into account that synthesized members such as operator= might not get marked as template specializations, because they're synthesized on the instantiation directly when handling the class-level dllexport attribute. llvm-svn: 342240 --- clang/lib/AST/ASTContext.cpp | 8 ++++++++ clang/test/CodeGen/pch-dllexport.cpp | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b107e8b..3d0d1e6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9724,6 +9724,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { cast(D)->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; + // Implicit member function definitions, such as operator= might not be + // marked as template specializations, since they're not coming from a + // template but synthesized directly on the class. + IsExpInstDef |= + isa(D) && + cast(D)->getParent()->getTemplateSpecializationKind() == + TSK_ExplicitInstantiationDefinition; + if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef) return false; } diff --git a/clang/test/CodeGen/pch-dllexport.cpp b/clang/test/CodeGen/pch-dllexport.cpp index 9c6623b..b8db075 100644 --- a/clang/test/CodeGen/pch-dllexport.cpp +++ b/clang/test/CodeGen/pch-dllexport.cpp @@ -57,6 +57,13 @@ extern template void explicitInstantiationDefAfterDecl(int); template T __declspec(dllexport) variableTemplate; extern template int variableTemplate; +namespace pr38934 { +template struct S {}; +extern template struct S; +// The use here causes the S::operator= decl to go into the PCH. +inline void use(S *a, S *b) { *a = *b; }; +} + #else void use() { @@ -81,4 +88,9 @@ template void __declspec(dllexport) explicitInstantiationDefAfterDecl(int); template int __declspec(dllexport) variableTemplate; // PCHWITHOBJVARS: @"??$variableTemplate@H@@3HA" = weak_odr dso_local dllexport global +// PR38934: Make sure S::operator= gets emitted. While it itself isn't a +// template specialization, its parent is. +template struct __declspec(dllexport) pr38934::S; +// PCHWITHOBJ: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable(1) %"struct.pr38934::S"* @"??4?$S@H@pr38934@@QAEAAU01@ABU01@@Z" + #endif -- 2.7.4