diff options
| author | Artem Belevich <tra@google.com> | 2016-05-09 22:09:56 +0000 |
|---|---|---|
| committer | Artem Belevich <tra@google.com> | 2016-05-09 22:09:56 +0000 |
| commit | 4d430badebaed4c7ff5a8af11890fbc177e77172 (patch) | |
| tree | 390941808308f3178d161870305ef13eca0a547a /clang/lib | |
| parent | a407f543c0d492c633a1e37adf61d743e07c1135 (diff) | |
| download | bcm5719-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.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 9 |
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 = |

