summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-05-07 21:19:06 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-05-07 21:19:06 +0000
commitec8e54bbefec9932cb0e26b020550d7c371acfb1 (patch)
treee7a299717afc16b9b3196b03254590de055e5d78 /clang
parent8d062ad560647fc0031735cb688cce5304f41046 (diff)
downloadbcm5719-llvm-ec8e54bbefec9932cb0e26b020550d7c371acfb1.tar.gz
bcm5719-llvm-ec8e54bbefec9932cb0e26b020550d7c371acfb1.zip
[MS ABI] Make sure we number thread_local statics seperately
The thread_local variables need their own numbers, they can't share with the other static local variables. llvm-svn: 236774
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/MicrosoftCXXABI.cpp5
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp6
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp23
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp12
4 files changed, 32 insertions, 14 deletions
diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp
index 4eb960a60dc..93ff77a2e96 100644
--- a/clang/lib/AST/MicrosoftCXXABI.cpp
+++ b/clang/lib/AST/MicrosoftCXXABI.cpp
@@ -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;
}
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 0bac4159e51..bac3472e683 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -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@";
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 431633e808e..35f59833726 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -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");
diff --git a/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
index 76583d0c6f9..5f6849dde03 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
@@ -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;
+}
OpenPOWER on IntegriCloud