]> granicus.if.org Git - clang/commitdiff
[MS ABI] Make sure we number thread_local statics seperately
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 7 May 2015 21:19:06 +0000 (21:19 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 7 May 2015 21:19:06 +0000 (21:19 +0000)
The thread_local variables need their own numbers, they can't share with
the other static local variables.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236774 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftCXXABI.cpp
lib/AST/MicrosoftMangle.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp

index 4eb960a60dc7f12a6242d5dd07854a330768b835..93ff77a2e9646d5b8b69aa157baeb75faffe9c07 100644 (file)
@@ -31,11 +31,12 @@ class MicrosoftNumberingContext : public MangleNumberingContext {
   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
   unsigned LambdaManglingNumber;
   unsigned StaticLocalNumber;
+  unsigned StaticThreadlocalNumber;
 
 public:
   MicrosoftNumberingContext()
       : MangleNumberingContext(), LambdaManglingNumber(0),
-        StaticLocalNumber(0) {}
+        StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
 
   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
     return ++LambdaManglingNumber;
@@ -47,6 +48,8 @@ public:
   }
 
   unsigned getStaticLocalNumber(const VarDecl *VD) override {
+    if (VD->getTLSKind())
+      return ++StaticThreadlocalNumber;
     return ++StaticLocalNumber;
   }
 
index 0bac4159e51dd9c7f8130ae5ee672e4bbd07c599..bac3472e68310cd32c6f1e1379baa5f16a1b2d71 100644 (file)
@@ -2534,6 +2534,7 @@ void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
 void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
                                                            raw_ostream &Out) {
   // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
+  //              ::= ?__J <postfix> @5 <scope-depth>
   //              ::= ?$S <guard-num> @ <postfix> @4IA
 
   // The first mangling is what MSVC uses to guard static locals in inline
@@ -2546,10 +2547,7 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
 
   bool Visible = VD->isExternallyVisible();
   if (Visible) {
-    Mangler.getStream() << (getASTContext().getLangOpts().isCompatibleWithMSVC(
-                                19)
-                                ? "\01??__J"
-                                : "\01??_B");
+    Mangler.getStream() << (VD->getTLSKind() ? "\01??__J" : "\01??_B");
   } else {
     Mangler.getStream() << "\01?$S1@";
   }
index 431633e808eaa3d939b6fae715d6e07f8316fac8..35f598337260af4dfce50202cc54dfa0aa287746 100644 (file)
@@ -687,6 +687,7 @@ private:
   /// Map from DeclContext to the current guard variable.  We assume that the
   /// AST is visited in source code order.
   llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
+  llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
   llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
 
   llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
@@ -2103,18 +2104,27 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
     return;
   }
 
-  bool HasPerVariableGuard =
-      getContext().getLangOpts().ThreadsafeStatics && !D.getTLSKind();
+  bool ThreadlocalStatic = D.getTLSKind();
+  bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
+
+  // Thread-safe static variables which aren't thread-specific have a
+  // per-variable guard.
+  bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
 
   CGBuilderTy &Builder = CGF.Builder;
   llvm::IntegerType *GuardTy = CGF.Int32Ty;
   llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
 
   // Get the guard variable for this function if we have one already.
-  GuardInfo *GI = &GuardVariableMap[D.getDeclContext()];
-  llvm::GlobalVariable *GuardVar = GI->Guard;
+  GuardInfo *GI = nullptr;
+  if (ThreadlocalStatic)
+    GI = &ThreadLocalGuardVariableMap[D.getDeclContext()];
+  else if (!ThreadsafeStatic)
+    GI = &GuardVariableMap[D.getDeclContext()];
+
+  llvm::GlobalVariable *GuardVar = GI ? GI->Guard : nullptr;
   unsigned GuardNum;
-  if (D.isStaticLocal() && D.isExternallyVisible()) {
+  if (D.isExternallyVisible()) {
     // Externally visible variables have to be numbered in Sema to properly
     // handle unreachable VarDecls.
     GuardNum = getContext().getStaticLocalNumber(&D);
@@ -2127,9 +2137,6 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
     GuardNum = GI->BitIndex++;
   }
 
-  if (HasPerVariableGuard)
-    GuardVar = nullptr;
-
   if (!HasPerVariableGuard && GuardNum >= 32) {
     if (D.isExternallyVisible())
       ErrorUnsupportedABI(CGF, "more than 32 guarded initializations");
index 76583d0c6f955a10c7aa1e3275cfe364ecd374fa..5f6849dde03831743aaf3bed0ca2df42dd93e122 100644 (file)
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// REQUIRES: asserts
+
 struct S {
   S();
   ~S();
@@ -9,6 +11,10 @@ struct S {
 // CHECK-DAG: @"\01?s@?1??g@@YAAAUS@@XZ@4U2@A" = linkonce_odr global %struct.S zeroinitializer
 // CHECK-DAG: @"\01?$TSS0@?1??g@@YAAAUS@@XZ" = linkonce_odr global i32 0
 // CHECK-DAG: @_Init_thread_epoch = external thread_local global i32, align 4
+// CHECK-DAG: @"\01?j@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr thread_local global %struct.S zeroinitializer
+// CHECK-DAG: @"\01??__J?1??h@@YAAAUS@@_N@Z@51" = linkonce_odr thread_local global i32 0
+// CHECK-DAG: @"\01?i@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr global %struct.S zeroinitializer
+// CHECK-DAG: @"\01?$TSS0@?1??h@@YAAAUS@@_N@Z" = linkonce_odr global i32 0
 
 // CHECK-LABEL: define {{.*}} @"\01?f@@YAAAUS@@XZ"()
 extern inline S &f() {
@@ -80,4 +86,8 @@ extern inline S &g() {
   return s;
 }
 
-// REQUIRES: asserts
+extern inline S&h(bool b) {
+  static thread_local S j;
+  static S i;
+  return b ? j : i;
+}