Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -7715,6 +7715,10 @@ "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_dereferencing : Error< "dereferencing pointer of type %0 is not allowed in OpenCL">; +def err_opencl_pointer_to_image : Error< + "pointer to image is invalid in OpenCL">; +def err_opencl_type_can_only_be_used_as_function_parameter : Error < + "%0 can only be used as a function parameter">; def err_opencl_block_proto_variadic : Error< "invalid block prototype, variadic arguments are not allowed in opencl">; def err_opencl_invalid_block_array : Error< Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5710,6 +5710,27 @@ QualType R = TInfo->getType(); DeclarationName Name = GetNameForDeclarator(D).getName(); + // OpenCL v2.0 s6.9.b + // An image type can only be used as a type of a function argument. + if (getLangOpts().OpenCL && R->isImageType()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << "image"; + D.setInvalidType(); + return nullptr; + } + + // OpenCL v2.0 s6.13.16.1 + // Pipes can only be passed as arguments to a function. + if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200 && + R->isPipeType()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << "pipe"; + D.setInvalidType(); + return nullptr; + } + DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); @@ -10744,6 +10765,15 @@ } } + // OpenCL v2.0 s6.9b2 - An image type cannot be used to declare a variable, a + // structure or union field, an array of images, a pointer to an image, or the + // return type of a function. + if (getLangOpts().OpenCL && T->isPointerType() && + T->getPointeeType()->isImageType()) { + Diag(NameLoc, diag::err_opencl_pointer_to_image); + New->setInvalidDecl(); + } + return New; } Index: test/CodeGenOpenCL/opencl_types.cl =================================================================== --- test/CodeGenOpenCL/opencl_types.cl +++ test/CodeGenOpenCL/opencl_types.cl @@ -35,6 +35,3 @@ fnc4smp(glb_smp); // CHECK: call {{.*}}void @fnc4smp(i32 } - -void __attribute__((overloadable)) bad1(image1d_t *b, image2d_t *c, image2d_t *d) {} -// CHECK-LABEL: @{{_Z4bad1P11ocl_image1dP11ocl_image2dS2_|"\\01\?bad1@@\$\$J0YAXPE?APAUocl_image1d@@PE?APAUocl_image2d@@1@Z"}} Index: test/SemaOpenCL/invalid-image.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/invalid-image.cl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify %s + +void test1(image1d_t *i){} // expected-error {{pointer to image is invalid in OpenCL}} + +void test2() { + image1d_t i; // expected-error {{image can only be used as a function parameter}} +} Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl =================================================================== --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -6,3 +6,6 @@ } void test3(int pipe p){// expected-error {{cannot combine with previous 'int' declaration specifier}} } +void test4() { + pipe int p; // expected-error {{pipe can only be used as a function parameter}} +}