Ayal updated this revision to Diff 497128. Ayal added a comment. Updated version merges the `if`'s and checks tests for both 1.2 and 2.0.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D143849/new/ https://reviews.llvm.org/D143849 Files: clang/lib/Sema/SemaDecl.cpp clang/test/SemaOpenCL/invalid-kernel-parameters.cl Index: clang/test/SemaOpenCL/invalid-kernel-parameters.cl =================================================================== --- clang/test/SemaOpenCL/invalid-kernel-parameters.cl +++ clang/test/SemaOpenCL/invalid-kernel-parameters.cl @@ -87,15 +87,20 @@ -typedef struct FooImage2D // expected-note{{within field of type 'FooImage2D' declared here}} +#if __OPENCL_C_VERSION__ <= CL_VERSION_1_2 +// expected-note@+4{{within field of type 'FooImage2D' declared here}} +// expected-note@+8{{field of illegal type '__read_only image2d_t' declared here}} +// expected-error@+10{{struct kernel parameters may not contain pointers}} +#endif +typedef struct FooImage2D { // TODO: Clean up needed - we don't really need to check for image, event, etc // as a note here any longer. // They are diagnosed as an error for all struct fields (OpenCL v1.2 s6.9b,r). - image2d_t imageField; // expected-note{{field of illegal type '__read_only image2d_t' declared here}} expected-error{{the '__read_only image2d_t' type cannot be used to declare a structure or union field}} + image2d_t imageField; // expected-error{{the '__read_only image2d_t' type cannot be used to declare a structure or union field}} } FooImage2D; -kernel void image_in_struct_arg(FooImage2D arg) { } // expected-error{{struct kernel parameters may not contain pointers}} +kernel void image_in_struct_arg(FooImage2D arg) { } typedef struct Foo // expected-note{{within field of type 'Foo' declared here}} { @@ -104,6 +109,18 @@ kernel void pointer_in_struct_arg(Foo arg) { } // expected-error{{struct kernel parameters may not contain pointers}} +#if __OPENCL_C_VERSION__ <= CL_VERSION_1_2 +// expected-note@+4{{within field of type 'FooGlobal' declared here}} +// expected-note@+5{{field of illegal pointer type '__global int *' declared here}} +// expected-error@+7{{struct kernel parameters may not contain pointers}} +#endif +typedef struct FooGlobal +{ + global int* ptrField; +} FooGlobal; + +kernel void global_pointer_in_struct_arg(FooGlobal arg) { } + 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}} Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -9489,13 +9489,18 @@ // 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. - if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam || - ParamType == InvalidAddrSpacePtrKernelParam) { + // union. This restriction was lifted in OpenCL v2.0 with the introduction + // of SVM. + if (ParamType == InvalidAddrSpacePtrKernelParam || + ((ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) && + S.getLangOpts().getOpenCLCompatibleVersion() <= 120)) { S.Diag(Param->getLocation(), diag::err_record_with_pointers_kernel_param) << PT->isUnionType() << PT; + } else if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) { + // and OpenCL version is at-least 2.0, so these types are allowed. + continue; } else { S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT; }
Index: clang/test/SemaOpenCL/invalid-kernel-parameters.cl =================================================================== --- clang/test/SemaOpenCL/invalid-kernel-parameters.cl +++ clang/test/SemaOpenCL/invalid-kernel-parameters.cl @@ -87,15 +87,20 @@ -typedef struct FooImage2D // expected-note{{within field of type 'FooImage2D' declared here}} +#if __OPENCL_C_VERSION__ <= CL_VERSION_1_2 +// expected-note@+4{{within field of type 'FooImage2D' declared here}} +// expected-note@+8{{field of illegal type '__read_only image2d_t' declared here}} +// expected-error@+10{{struct kernel parameters may not contain pointers}} +#endif +typedef struct FooImage2D { // TODO: Clean up needed - we don't really need to check for image, event, etc // as a note here any longer. // They are diagnosed as an error for all struct fields (OpenCL v1.2 s6.9b,r). - image2d_t imageField; // expected-note{{field of illegal type '__read_only image2d_t' declared here}} expected-error{{the '__read_only image2d_t' type cannot be used to declare a structure or union field}} + image2d_t imageField; // expected-error{{the '__read_only image2d_t' type cannot be used to declare a structure or union field}} } FooImage2D; -kernel void image_in_struct_arg(FooImage2D arg) { } // expected-error{{struct kernel parameters may not contain pointers}} +kernel void image_in_struct_arg(FooImage2D arg) { } typedef struct Foo // expected-note{{within field of type 'Foo' declared here}} { @@ -104,6 +109,18 @@ kernel void pointer_in_struct_arg(Foo arg) { } // expected-error{{struct kernel parameters may not contain pointers}} +#if __OPENCL_C_VERSION__ <= CL_VERSION_1_2 +// expected-note@+4{{within field of type 'FooGlobal' declared here}} +// expected-note@+5{{field of illegal pointer type '__global int *' declared here}} +// expected-error@+7{{struct kernel parameters may not contain pointers}} +#endif +typedef struct FooGlobal +{ + global int* ptrField; +} FooGlobal; + +kernel void global_pointer_in_struct_arg(FooGlobal arg) { } + 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}} Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -9489,13 +9489,18 @@ // 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. - if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam || - ParamType == InvalidAddrSpacePtrKernelParam) { + // union. This restriction was lifted in OpenCL v2.0 with the introduction + // of SVM. + if (ParamType == InvalidAddrSpacePtrKernelParam || + ((ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) && + S.getLangOpts().getOpenCLCompatibleVersion() <= 120)) { S.Diag(Param->getLocation(), diag::err_record_with_pointers_kernel_param) << PT->isUnionType() << PT; + } else if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) { + // and OpenCL version is at-least 2.0, so these types are allowed. + continue; } else { S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits