From: David Majnemer Date: Fri, 17 Jul 2015 23:36:49 +0000 (+0000) Subject: [MS ABI] Explicit specialization of static data members are weak X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3daaf3ddc5887622a8f64147a75512b65e97a1fd;p=clang [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 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242592 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index fb9630180d..61bd107794 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -8285,9 +8285,13 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, 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; diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp index 4038d0ba46..da9e19cb15 100644 --- a/test/CodeGenCXX/dllexport-members.cpp +++ b/test/CodeGenCXX/dllexport-members.cpp @@ -623,13 +623,13 @@ extern template const int MemVarTmpl::ExportedStaticVar; template const int MemVarTmpl::ExportedStaticVar; // 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 = 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 = 1; @@ -648,6 +648,6 @@ extern template __declspec(dllexport) const int MemVarTmpl::StaticVar; // 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 = 1; diff --git a/test/CodeGenCXX/microsoft-compatibility.cpp b/test/CodeGenCXX/microsoft-compatibility.cpp index 297184a1df..36760243d4 100644 --- a/test/CodeGenCXX/microsoft-compatibility.cpp +++ b/test/CodeGenCXX/microsoft-compatibility.cpp @@ -1,5 +1,15 @@ // RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -fms-compatibility -emit-llvm -o - | FileCheck %s +template +struct S { + static const int x[]; +}; + +template <> +const int S::x[] = {1}; + +// CHECK-LABEL: @"\01?x@?$S@D@@2QBHB" = weak_odr constant [1 x i32] [i32 1], comdat + template void destroy(T *p) { p->~T();