diff options
| author | Jingyue Wu <jingyue@google.com> | 2015-03-25 20:06:28 +0000 |
|---|---|---|
| committer | Jingyue Wu <jingyue@google.com> | 2015-03-25 20:06:28 +0000 |
| commit | 4f7b9eb217f0a065acffe81189599b7db49a0792 (patch) | |
| tree | bbfeca6d434823c51a752cb7a38fadd2c4469617 /clang/lib/CodeGen | |
| parent | f9dc7036d3d2f9d0de41a1be127a41d7a9728c78 (diff) | |
| download | bcm5719-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.cpp | 23 |
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( |

