summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArtem Belevich <tra@google.com>2016-05-09 22:09:56 +0000
committerArtem Belevich <tra@google.com>2016-05-09 22:09:56 +0000
commit4d430badebaed4c7ff5a8af11890fbc177e77172 (patch)
tree390941808308f3178d161870305ef13eca0a547a /clang/lib
parenta407f543c0d492c633a1e37adf61d743e07c1135 (diff)
downloadbcm5719-llvm-4d430badebaed4c7ff5a8af11890fbc177e77172.tar.gz
bcm5719-llvm-4d430badebaed4c7ff5a8af11890fbc177e77172.zip
[CUDA] Restrict init of local __shared__ variables to empty constructors only.
Allow only empty constructors for local __shared__ variables in a way identical to restrictions imposed on dynamic initializers for global variables on device. Differential Revision: http://reviews.llvm.org/D20039 llvm-svn: 268982
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp10
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
2 files changed, 13 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index c39b980ef2c..b6ab75f67cc 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -371,8 +371,15 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
llvm::GlobalVariable *var =
cast<llvm::GlobalVariable>(addr->stripPointerCasts());
+
+ // CUDA's local and local static __shared__ variables should not
+ // have any non-empty initializers. This is ensured by Sema.
+ // Whatever initializer such variable may have when it gets here is
+ // a no-op and should not be emitted.
+ bool isCudaSharedVar = getLangOpts().CUDA && getLangOpts().CUDAIsDevice &&
+ D.hasAttr<CUDASharedAttr>();
// If this value has an initializer, emit it.
- if (D.getInit())
+ if (D.getInit() && !isCudaSharedVar)
var = AddInitializerToStaticVarDecl(D, var);
var->setAlignment(alignment.getQuantity());
@@ -1874,4 +1881,3 @@ void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
return;
getOpenMPRuntime().emitUserDefinedReduction(CGF, D);
}
-
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a2c28de5f56..020b474c187 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10414,14 +10414,15 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
// Perform check for initializers of device-side global variables.
// CUDA allows empty constructors as initializers (see E.2.3.1, CUDA
- // 7.5). CUDA also allows constant initializers for __constant__ and
- // __device__ variables.
+ // 7.5). We must also apply the same checks to all __shared__
+ // variables whether they are local or not. CUDA also allows
+ // constant initializers for __constant__ and __device__ variables.
if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) {
const Expr *Init = VD->getInit();
- const bool IsGlobal = VD->hasGlobalStorage() && !VD->isStaticLocal();
- if (Init && IsGlobal &&
+ if (Init && VD->hasGlobalStorage() &&
(VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>() ||
VD->hasAttr<CUDASharedAttr>())) {
+ assert((!VD->isStaticLocal() || VD->hasAttr<CUDASharedAttr>()));
bool AllowedInit = false;
if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Init))
AllowedInit =
OpenPOWER on IntegriCloud