r242592 - [MS ABI] Explicit specialization of static data members are weak

David Majnemer david.majnemer at gmail.com
Fri Jul 17 16:36:49 PDT 2015


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 at UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar at 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 at UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar at 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 at UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$StaticVar at 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 at D@@2QBHB" = weak_odr constant [1 x i32] [i32 1], comdat
+
 template<class T>
 void destroy(T *p) {
   p->~T();





More information about the cfe-commits mailing list