summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorJingyue Wu <jingyue@google.com>2015-03-25 20:06:28 +0000
committerJingyue Wu <jingyue@google.com>2015-03-25 20:06:28 +0000
commit4f7b9eb217f0a065acffe81189599b7db49a0792 (patch)
treebbfeca6d434823c51a752cb7a38fadd2c4469617 /clang/lib/CodeGen
parentf9dc7036d3d2f9d0de41a1be127a41d7a9728c78 (diff)
downloadbcm5719-llvm-4f7b9eb217f0a065acffe81189599b7db49a0792.tar.gz
bcm5719-llvm-4f7b9eb217f0a065acffe81189599b7db49a0792.zip
Fix addrspace when emitting constructors of static local variables
Summary: Due to CUDA's implicit address space casting, the type of a static local variable may be more specific (i.e. with address space qualifiers) than the type expected by the constructor. Emit an addrspacecast in that case. Test Plan: Clang used to crash on the added test. Reviewers: nlewycky, pcc, eliben, rsmith Reviewed By: eliben, rsmith Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8575 llvm-svn: 233208
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 9a4303e5c13..236337b4034 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -139,6 +139,29 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
const Expr *Init = D.getInit();
QualType T = D.getType();
+ // The address space of a static local variable (DeclPtr) may be different
+ // from the address space of the "this" argument of the constructor. In that
+ // case, we need an addrspacecast before calling the constructor.
+ //
+ // struct StructWithCtor {
+ // __device__ StructWithCtor() {...}
+ // };
+ // __device__ void foo() {
+ // __shared__ StructWithCtor s;
+ // ...
+ // }
+ //
+ // For example, in the above CUDA code, the static local variable s has a
+ // "shared" address space qualifier, but the constructor of StructWithCtor
+ // expects "this" in the "generic" address space.
+ unsigned ExpectedAddrSpace = getContext().getTargetAddressSpace(T);
+ unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
+ if (ActualAddrSpace != ExpectedAddrSpace) {
+ llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(T);
+ llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
+ DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
+ }
+
if (!T->isReferenceType()) {
if (getLangOpts().OpenMP && D.hasAttr<OMPThreadPrivateDeclAttr>())
(void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
OpenPOWER on IntegriCloud