Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -9273,6 +9273,12 @@ ParamKind == InvalidKernelParam) return ParamKind; + // OpenCL v3.0 s6.11.a: + // A restriction to pass pointers to pointers only applies to OpenCL C + // v1.2 or below. + if (S.getLangOpts().getOpenCLCompatibleVersion() > 120) + return ValidKernelParam; + return PtrPtrKernelParam; } @@ -9300,6 +9306,11 @@ return InvalidKernelParam; } + // OpenCL v1.2 s6.9.p: + // A restriction to pass pointers only applies to OpenCL C v1.2 or below. + if (S.getLangOpts().getOpenCLCompatibleVersion() > 120) + return ValidKernelParam; + return PtrKernelParam; } @@ -9366,13 +9377,8 @@ // OpenCL v3.0 s6.11.a: // A kernel function argument cannot be declared as a pointer to a pointer // type. [...] This restriction only applies to OpenCL C 1.2 or below. - if (S.getLangOpts().getOpenCLCompatibleVersion() <= 120) { - S.Diag(Param->getLocation(), diag::err_opencl_ptrptr_kernel_param); - D.setInvalidType(); - return; - } - - ValidTypes.insert(PT.getTypePtr()); + S.Diag(Param->getLocation(), diag::err_opencl_ptrptr_kernel_param); + D.setInvalidType(); return; case InvalidAddrSpacePtrKernelParam: @@ -9490,7 +9496,8 @@ // OpenCL v1.2 s6.9.p: // Arguments to kernel functions that are declared to be a struct or union // do not allow OpenCL objects to be passed as elements of the struct or - // union. + // union. This restriction was lifted in OpenCL v2.0 with the introduction + // of SVM. if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam || ParamType == InvalidAddrSpacePtrKernelParam) { S.Diag(Param->getLocation(), Index: clang/test/SemaOpenCL/invalid-kernel-parameters.cl =================================================================== --- clang/test/SemaOpenCL/invalid-kernel-parameters.cl +++ clang/test/SemaOpenCL/invalid-kernel-parameters.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -triple spir-unknown-unknown +// RUN: %clang_cc1 -fsyntax-only -verify=expected,ocl12 %s -triple spir-unknown-unknown // RUN: %clang_cc1 -fsyntax-only -verify %s -triple spir-unknown-unknown -cl-std=CL2.0 kernel void half_arg(half x) { } // expected-error{{declaring function parameter of type '__private half' is not allowed; did you forget * ?}} @@ -104,6 +104,13 @@ kernel void pointer_in_struct_arg(Foo arg) { } // expected-error{{struct kernel parameters may not contain pointers}} +typedef struct FooGlobal // ocl12-note{{within field of type 'FooGlobal' declared here}} +{ + global int* ptrField; // ocl12-note{{field of illegal pointer type '__global int *' declared here}} +} FooGlobal; + +kernel void global_pointer_in_struct_arg(FooGlobal arg) { } // ocl12-error{{struct kernel parameters may not contain pointers}} + typedef union FooUnion // expected-note{{within field of type 'FooUnion' declared here}} { int* ptrField; // expected-note-re{{field of illegal pointer type '__{{private|generic}} int *' declared here}}