diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2017-06-20 14:50:45 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2017-06-20 14:50:45 +0000 |
commit | e437b6a52b7def19dfc61f72f71d6c63b5f623cc (patch) | |
tree | 5e46696a691c3d2aa78db8301d4bd48eb86ea4e3 | |
parent | ad870f82858671c5089809bda1286780506f4c81 (diff) | |
download | llvm-e437b6a52b7def19dfc61f72f71d6c63b5f623cc.zip llvm-e437b6a52b7def19dfc61f72f71d6c63b5f623cc.tar.gz llvm-e437b6a52b7def19dfc61f72f71d6c63b5f623cc.tar.bz2 |
[OpenCL] Diagnose scoped address-space qualified variables
Produce an error if variables qualified with a local or
a constant address space are not declared in the outermost
scope of a kernel.
Patch by Simon Perretta.
Differential Revision: https://reviews.llvm.org/D34024
llvm-svn: 305798
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 | ||||
-rw-r--r-- | clang/test/SemaOpenCL/storageclass.cl | 5 |
3 files changed, 24 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 36b41c3..0dd151c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8311,6 +8311,9 @@ def err_opencl_ext_vector_component_invalid_length : Error< "vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">; def err_opencl_function_variable : Error< "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; +def err_opencl_addrspace_scope : Error< + "variables in the %0 address space can only be declared in the outermost " + "scope of a kernel function">; def err_static_function_scope : Error< "variables in function scope cannot be declared static">; def err_opencl_bitfields : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index cba220d..d6164b3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7260,11 +7260,11 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { NewVD->setInvalidDecl(); return; } - // OpenCL v1.1 s6.5.2 and s6.5.3 no local or constant variables - // in functions. if (T.getAddressSpace() == LangAS::opencl_constant || T.getAddressSpace() == LangAS::opencl_local) { FunctionDecl *FD = getCurFunctionDecl(); + // OpenCL v1.1 s6.5.2 and s6.5.3: no local or constant variables + // in functions. if (FD && !FD->hasAttr<OpenCLKernelAttr>()) { if (T.getAddressSpace() == LangAS::opencl_constant) Diag(NewVD->getLocation(), diag::err_opencl_function_variable) @@ -7275,6 +7275,20 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { NewVD->setInvalidDecl(); return; } + // OpenCL v2.0 s6.5.2 and s6.5.3: local and constant variables must be + // in the outermost scope of a kernel function. + if (FD && FD->hasAttr<OpenCLKernelAttr>()) { + if (!getCurScope()->isFunctionScope()) { + if (T.getAddressSpace() == LangAS::opencl_constant) + Diag(NewVD->getLocation(), diag::err_opencl_addrspace_scope) + << "constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_addrspace_scope) + << "local"; + NewVD->setInvalidDecl(); + return; + } + } } else if (T.getAddressSpace() != LangAS::Default) { // Do not allow other address spaces on automatic variable. Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1; diff --git a/clang/test/SemaOpenCL/storageclass.cl b/clang/test/SemaOpenCL/storageclass.cl index e611313..9a46106 100644 --- a/clang/test/SemaOpenCL/storageclass.cl +++ b/clang/test/SemaOpenCL/storageclass.cl @@ -13,6 +13,11 @@ void kernel foo(int x) { constant int L1 = 0; local int L2; + if (true) { + local int L1; // expected-error {{variables in the local address space can only be declared in the outermost scope of a kernel function}} + constant int L1 = 42; // expected-error {{variables in the constant address space can only be declared in the outermost scope of a kernel function}} + } + auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}} global int L4; // expected-error{{function scope variable cannot be declared in global address space}} __attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}} |