Author: majnemer Date: Fri Jul 17 18:36:49 2015 New Revision: 242592 URL: http://llvm.org/viewvc/llvm-project?rev=242592&view=rev Log: [MS ABI] Explicit specialization of static data members are weak
Normally, explicit specializations are treated like strong external definitions. However, MSVC treats explicit specializations of static data members as weak. MSVC 2013's <regex> implementation has such an explicit specialization which leads to clang emitting a strong definition in each translation unit which includes it. Tweak clang's linkage calculation to give such entities GVA_StrongODR linkage instead. This fixes PR24165. Modified: cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/test/CodeGenCXX/dllexport-members.cpp cfe/trunk/test/CodeGenCXX/microsoft-compatibility.cpp Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=242592&r1=242591&r2=242592&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jul 17 18:36:49 2015 @@ -8285,9 +8285,13 @@ static GVALinkage basicGVALinkageForVari switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: - case TSK_ExplicitSpecialization: return GVA_StrongExternal; + case TSK_ExplicitSpecialization: + return Context.getLangOpts().MSVCCompat && VD->isStaticDataMember() + ? GVA_StrongODR + : GVA_StrongExternal; + case TSK_ExplicitInstantiationDefinition: return GVA_StrongODR; Modified: cfe/trunk/test/CodeGenCXX/dllexport-members.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport-members.cpp?rev=242592&r1=242591&r2=242592&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllexport-members.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dllexport-members.cpp Fri Jul 17 18:36:49 2015 @@ -623,13 +623,13 @@ extern template const int MemVarTmpl::Ex template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>; // Export specialization of an exported member variable template. -// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 // GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI25ExplicitSpec_Def_ExportedEE = dllexport constant i32 1, align 4 template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1; // Not exporting specialization of an exported member variable template without // explicit dllexport. -// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = constant i32 1, align 4 +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = weak_odr constant i32 1, comdat, align 4 // GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI24ExplicitSpec_NotExportedEE = constant i32 1, align 4 template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1; @@ -648,6 +648,6 @@ extern template __declspec(dllexport) co template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>; // Export specialization of a non-exported member variable template. -// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 // GNU-DAG: @_ZN10MemVarTmpl9StaticVarI25ExplicitSpec_Def_ExportedEE = dllexport constant i32 1, align 4 template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1; Modified: cfe/trunk/test/CodeGenCXX/microsoft-compatibility.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-compatibility.cpp?rev=242592&r1=242591&r2=242592&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-compatibility.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-compatibility.cpp Fri Jul 17 18:36:49 2015 @@ -1,5 +1,15 @@ // RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -fms-compatibility -emit-llvm -o - | FileCheck %s +template <typename> +struct S { + static const int x[]; +}; + +template <> +const int S<char>::x[] = {1}; + +// CHECK-LABEL: @"\01?x@?$S@D@@2QBHB" = weak_odr constant [1 x i32] [i32 1], comdat + template<class T> void destroy(T *p) { p->~T(); _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits