summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-04-14 23:01:42 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-04-14 23:01:42 +0000
commitdbf74baee576ba200009bcead0117cc641d39071 (patch)
tree98577d678a6974765c016c31024abc4ee444b2d8 /clang/lib/CodeGen/CGExpr.cpp
parente45f58d8a90c2e9fbf4cf46dcf29f27e0deb3077 (diff)
downloadbcm5719-llvm-dbf74baee576ba200009bcead0117cc641d39071.tar.gz
bcm5719-llvm-dbf74baee576ba200009bcead0117cc641d39071.zip
CodeGen support for function-local static thread_local variables with
non-constant constructors or non-trivial destructors. Plus bugfixes for thread_local references bound to temporaries (the temporaries themselves are lifetime-extended to become thread_local), and the corresponding case for std::initializer_list. llvm-svn: 179496
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c5155088758..1c06b7d2d98 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -184,12 +184,16 @@ CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type,
llvm::Type *RefTempTy = CGF.ConvertTypeForMem(Type);
// Create the reference temporary.
- llvm::GlobalValue *RefTemp =
+ llvm::GlobalVariable *RefTemp =
new llvm::GlobalVariable(CGF.CGM.getModule(),
RefTempTy, /*isConstant=*/false,
llvm::GlobalValue::InternalLinkage,
llvm::Constant::getNullValue(RefTempTy),
Name.str());
+ // If we're binding to a thread_local variable, the temporary is also
+ // thread local.
+ if (VD->getTLSKind())
+ CGF.CGM.setTLSMode(RefTemp, *VD);
return RefTemp;
}
}
@@ -434,12 +438,15 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
CleanupArg = cast<llvm::Constant>(ReferenceTemporary);
}
- CGM.getCXXABI().registerGlobalDtor(*this, CleanupFn, CleanupArg);
+ CGM.getCXXABI().registerGlobalDtor(*this, *VD, CleanupFn, CleanupArg);
} else if (ReferenceInitializerList) {
+ // FIXME: This is wrong. We need to register a global destructor to clean
+ // up the initializer_list object, rather than adding it as a local
+ // cleanup.
EmitStdInitializerListCleanup(ReferenceTemporary,
ReferenceInitializerList);
} else {
- assert(!ObjCARCReferenceLifetimeType.isNull());
+ assert(!ObjCARCReferenceLifetimeType.isNull() && !VD->getTLSKind());
// Note: We intentionally do not register a global "destructor" to
// release the object.
}
OpenPOWER on IntegriCloud