Author: smeenai Date: Thu Jan 12 19:28:34 2017 New Revision: 291877 URL: http://llvm.org/viewvc/llvm-project?rev=291877&view=rev Log: [Sema] Restrict explicit instantation definition dllexport
In the case where the template class itself is already `dllexport`, the implicit instantiation will have already emitted all members. When we check the explicit instantiation definition, the `Specialization` will have inherited the `dllexport` attribute, so we'll attempt to emit all members for a second time, which causes an assertion failure. Restrict the exporting to when the `dllexport` attribute is newly introduced by the explicit instantiation definition. Fixes PR31608. Differential Revision: https://reviews.llvm.org/D28590 Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CodeGenCXX/dllexport.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=291877&r1=291876&r2=291877&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jan 12 19:28:34 2017 @@ -7789,6 +7789,7 @@ Sema::ActOnExplicitInstantiation(Scope * Specialization->setTemplateKeywordLoc(TemplateLoc); Specialization->setBraceRange(SourceRange()); + bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>(); if (Attr) ProcessDeclAttributeList(S, Specialization, Attr); @@ -7851,8 +7852,9 @@ Sema::ActOnExplicitInstantiation(Scope * // Fix a TSK_ImplicitInstantiation followed by a // TSK_ExplicitInstantiationDefinition - if (Old_TSK == TSK_ImplicitInstantiation && - Specialization->hasAttr<DLLExportAttr>() && + bool NewlyDLLExported = + !PreviouslyDLLExported && Specialization->hasAttr<DLLExportAttr>(); + if (Old_TSK == TSK_ImplicitInstantiation && NewlyDLLExported && (Context.getTargetInfo().getCXXABI().isMicrosoft() || Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) { // In the MS ABI, an explicit instantiation definition can add a dll Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=291877&r1=291876&r2=291877&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Thu Jan 12 19:28:34 2017 @@ -732,13 +732,27 @@ USEMEMFUNC(ExplicitInstantiationDeclExpo // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ" // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv -template <typename T> struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate { void f() {} }; +template <typename T> struct ImplicitInstantiationExportedExplicitInstantiationDefTemplate { virtual void f() {} }; +ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefTemplateInstance; +template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>; +USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>, f); +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExportedExplicitInstantiationDefTemplate@H@@UAEXXZ" +// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExportedExplicitInstantiationDefTemplateIiE1fEv + +template <typename T> struct __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate { virtual void f() {} }; ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance; -template class __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>; +template struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>; USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>, f); -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@QAEXXZ" +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@UAEXXZ" // G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv +template <typename T> struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate { virtual void f() {} }; +ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateInstance; +template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>; +USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>, f); +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate@H@@UAEXXZ" +// G32-DAG: define weak_odr x86_thiscallcc void @_ZN69ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateIiE1fEv + namespace { struct InternalLinkageType {}; } struct __declspec(dllexport) PR23308 { void f(InternalLinkageType*); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits