Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -7678,7 +7678,7 @@ def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; def err_opencl_global_invalid_addr_space : Error< - "program scope variable must reside in %0 address space">; + "program scope %select{variable|pointer}0 must %select{reside in|point to}0 %1 address space">; def err_missing_actual_pipe_type : Error< "missing actual type specifier for pipe">; def err_reference_pipe_type : Error < Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -6600,37 +6600,34 @@ // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static // variables inside a function can also be declared in the global // address space. - if (NewVD->isFileVarDecl()) { - if (!T->isSamplerT() && - !(T.getAddressSpace() == LangAS::opencl_constant || - (T.getAddressSpace() == LangAS::opencl_global && - getLangOpts().OpenCLVersion == 200))) { - if (getLangOpts().OpenCLVersion == 200) - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << "global or constant"; - else - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << "constant"; - NewVD->setInvalidDecl(); - return; - } + if (NewVD->isFileVarDecl() || NewVD->isStaticLocal()) { + // Program scope pointers can only point to data at the constant or global + // address space. + const PointerType *PT = nullptr; + bool IsPointerDecl = false; + do { + if (!T->isSamplerT() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), + diag::err_opencl_global_invalid_addr_space) + << IsPointerDecl << "global or constant"; + else + Diag(NewVD->getLocation(), + diag::err_opencl_global_invalid_addr_space) + << IsPointerDecl << "constant"; + NewVD->setInvalidDecl(); + return; + } + PT = dyn_cast(T.getTypePtr()); + if (PT) { + T = PT->getPointeeType(); + IsPointerDecl = true; + } + } while (PT); } else { - // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static - // variables inside a function can also be declared in the global - // address space. - if (NewVD->isStaticLocal() && - !(T.getAddressSpace() == LangAS::opencl_constant || - (T.getAddressSpace() == LangAS::opencl_global && - getLangOpts().OpenCLVersion == 200))) { - if (getLangOpts().OpenCLVersion == 200) - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << "global or constant"; - else - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << "constant"; - 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 || Index: test/CodeGenOpenCL/address-spaces.cl =================================================================== --- test/CodeGenOpenCL/address-spaces.cl +++ test/CodeGenOpenCL/address-spaces.cl @@ -28,8 +28,8 @@ #ifdef CL20 int i; // CL20-DAG: @i = common addrspace(1) global i32 0 -int *ptr; -// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null +global int *ptr; +// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(1)* null #endif // CHECK: i32* %arg Index: test/SemaOpenCL/storageclass-cl20.cl =================================================================== --- test/SemaOpenCL/storageclass-cl20.cl +++ test/SemaOpenCL/storageclass-cl20.cl @@ -3,12 +3,16 @@ static constant int G1 = 0; int G2 = 0; global int G3 = 0; -local int G4 = 0;// expected-error{{program scope variable must reside in global or constant address space}} +local int G4 = 0; // expected-error{{program scope variable must reside in global or constant address space}} +global int **constant GP5 = 0; // expected-error{{program scope pointer must point to global or constant address space}} +global int *global GP6 = 0; void kernel foo() { static int S1 = 5; static global int S2 = 5; - static private int S3 = 5;// expected-error{{program scope variable must reside in global or constant address space}} + static private int S3 = 5; // expected-error{{program scope variable must reside in global or constant address space}} + static local int *global S4; // expected-error{{program scope pointer must point to global or constant address space}} + static constant int *global S5; constant int L1 = 0; local int L2; Index: test/SemaOpenCL/storageclass.cl =================================================================== --- test/SemaOpenCL/storageclass.cl +++ test/SemaOpenCL/storageclass.cl @@ -5,6 +5,13 @@ int G3 = 0; // expected-error{{program scope variable must reside in constant address space}} global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}} +int *constant GP1 = 0; // expected-error{{program scope pointer must point to constant address space}} +int *constant *constant GP2 = 0; // expected-error{{program scope pointer must point to constant address space}} +int **constant GP3 = 0; // expected-error{{program scope pointer must point to constant address space}} +constant int **constant GP4 = 0; // expected-error{{program scope pointer must point to constant address space}} +global int *constant GP5 = 0; // expected-error{{program scope pointer must point to constant address space}} +constant int *constant GP6 = 0; + void kernel foo() { // static is not allowed at local scope before CL2.0 static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}}