diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7552,18 +7552,17 @@ // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the // __opencl_c_read_write_images feature, image objects specified as arguments // to a kernel can additionally be declared to be read-write. - // C++ for OpenCL inherits rule from OpenCL C v2.0. + // C++ for OpenCL 1.0 inherits rule from OpenCL C v2.0. + // C++ for OpenCL 2021 inherits rule from OpenCL C v3.0. if (const auto *PDecl = dyn_cast(D)) { const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr(); if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) { - bool ReadWriteImagesUnsupportedForOCLC = - (S.getLangOpts().OpenCLVersion < 200) || - (S.getLangOpts().OpenCLVersion == 300 && + bool ReadWriteImagesUnsupported = + (S.getLangOpts().getOpenCLCompatibleVersion() < 200) || + (S.getLangOpts().getOpenCLCompatibleVersion() == 300 && !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images", S.getLangOpts())); - if ((!S.getLangOpts().OpenCLCPlusPlus && - ReadWriteImagesUnsupportedForOCLC) || - DeclTy->isPipeType()) { + if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) { S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write) << AL << PDecl->getType() << DeclTy->isImageType(); D->setInvalidDecl(true); diff --git a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl --- a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl +++ b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl @@ -3,6 +3,7 @@ // RUN: not %clang_cc1 -cl-std=clc++2021 -triple spir-unknown-unknown -cl-ext=-__opencl_c_fp64,+cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s // RUN: not %clang_cc1 -cl-std=clc++2021 -triple spir-unknown-unknown -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_read_write_images,-__opencl_c_images %s 2>&1 | FileCheck -check-prefix=CHECK-READ-WRITE-IMAGES %s +// RUN: not %clang_cc1 -cl-std=clc++2021 -triple spir-unknown-unknown -cl-ext=+__opencl_c_read_write_images,-__opencl_c_images %s 2>&1 | FileCheck -check-prefix=CHECK-READ-WRITE-IMAGES %s // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_pipes,-__opencl_c_generic_address_space %s 2>&1 | FileCheck -check-prefix=CHECK-PIPES %s // RUN: not %clang_cc1 -cl-std=clc++2021 -triple spir-unknown-unknown -cl-ext=+__opencl_c_pipes,-__opencl_c_generic_address_space %s 2>&1 | FileCheck -check-prefix=CHECK-PIPES %s // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_3d_image_writes,+__opencl_c_images,-cl_khr_3d_image_writes %s 2>&1 | FileCheck -check-prefix=CHECK-3D-WRITE-IMAGES-DIFF %s diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl --- a/clang/test/SemaOpenCL/access-qualifier.cl +++ b/clang/test/SemaOpenCL/access-qualifier.cl @@ -2,24 +2,38 @@ // RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s // RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL3.0 %s // RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL3.0 %s -cl-ext=-__opencl_c_read_write_images +// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=clc++2021 %s +// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=clc++2021 %s -cl-ext=-__opencl_c_read_write_images typedef image1d_t img1d_ro_default; // expected-note {{previously declared 'read_only' here}} typedef write_only image1d_t img1d_wo; // expected-note {{previously declared 'write_only' here}} typedef read_only image1d_t img1d_ro; -#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) +#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images)) typedef read_write image1d_t img1d_rw; #endif typedef int Int; typedef read_only int IntRO; // expected-error {{access qualifier can only be used for pipe and image type}} +void myWrite(write_only image1d_t); +#if !defined(__OPENCL_CPP_VERSION__) +// expected-note@-2 {{passing argument to parameter here}} +// expected-note@-3 {{passing argument to parameter here}} +#else +// expected-note@-5 {{candidate function not viable: no known conversion from '__private img1d_ro' (aka '__private __read_only image1d_t') to '__private __write_only image1d_t' for 1st argument}} +// expected-note@-6 {{candidate function not viable: no known conversion from '__private img1d_ro_default' (aka '__private __read_only image1d_t') to '__private __write_only image1d_t' for 1st argument}} +#endif -void myWrite(write_only image1d_t); // expected-note {{passing argument to parameter here}} expected-note {{passing argument to parameter here}} -void myRead(read_only image1d_t); // expected-note {{passing argument to parameter here}} +void myRead(read_only image1d_t); +#if !defined(__OPENCL_CPP_VERSION__) +// expected-note@-2 {{passing argument to parameter here}} +#else +// expected-note@-4 {{candidate function not viable: no known conversion from '__private img1d_wo' (aka '__private __write_only image1d_t') to '__private __read_only image1d_t' for 1st argument}} +#endif -#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) +#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images)) void myReadWrite(read_write image1d_t); #else void myReadWrite(read_write image1d_t); // expected-error {{access qualifier 'read_write' can not be used for '__read_write image1d_t' prior to OpenCL C version 2.0 or in version 3.0 and without __opencl_c_read_write_images feature}} @@ -27,25 +41,40 @@ kernel void k1(img1d_wo img) { - myRead(img); // expected-error {{passing '__private img1d_wo' (aka '__private __write_only image1d_t') to parameter of incompatible type '__read_only image1d_t'}} + myRead(img); +#if !defined(__OPENCL_CPP_VERSION__) +// expected-error@-2 {{passing '__private img1d_wo' (aka '__private __write_only image1d_t') to parameter of incompatible type '__read_only image1d_t'}} +#else +// expected-error@-4 {{no matching function for call to 'myRead'}} +#endif } kernel void k2(img1d_ro img) { - myWrite(img); // expected-error {{passing '__private img1d_ro' (aka '__private __read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} + myWrite(img); +#if !defined(__OPENCL_CPP_VERSION__) +// expected-error@-2 {{passing '__private img1d_ro' (aka '__private __read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} +#else +// expected-error@-4 {{no matching function for call to 'myWrite'}} +#endif } kernel void k3(img1d_wo img) { myWrite(img); } -#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) +#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images)) kernel void k4(img1d_rw img) { myReadWrite(img); } #endif kernel void k5(img1d_ro_default img) { - myWrite(img); // expected-error {{passing '__private img1d_ro_default' (aka '__private __read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} + myWrite(img); +#if !defined(__OPENCL_CPP_VERSION__) +// expected-error@-2 {{passing '__private img1d_ro_default' (aka '__private __read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} +#else +// expected-error@-4 {{no matching function for call to 'myWrite'}} +#endif } kernel void k6(img1d_ro img) { @@ -64,19 +93,19 @@ kernel void k12(read_only read_only image1d_t i){} // expected-warning {{duplicate 'read_only' declaration specifier}} -#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) +#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images)) kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}} #else kernel void k13(__read_write image1d_t i){} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' prior to OpenCL C version 2.0 or in version 3.0 and without __opencl_c_read_write_images feature}} #endif -#if __OPENCL_C_VERSION__ < 200 +#if defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 200 kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes support}} #endif -#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) +#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images)) kernel void read_write_twice_typedef(read_write img1d_rw i){} // expected-warning {{duplicate 'read_write' declaration specifier}} -// expected-note@-67 {{previously declared 'read_write' here}} +// expected-note@-94 {{previously declared 'read_write' here}} #endif #if __OPENCL_C_VERSION__ >= 200 @@ -101,12 +130,11 @@ #endif kernel void read_only_twice_typedef(__read_only img1d_ro i){} // expected-warning {{duplicate '__read_only' declaration specifier}} -// expected-note@-95 {{previously declared 'read_only' here}} +// expected-note@-122 {{previously declared 'read_only' here}} kernel void read_only_twice_default(read_only img1d_ro_default img){} // expected-warning {{duplicate 'read_only' declaration specifier}} -// expected-note@-101 {{previously declared 'read_only' here}} +// expected-note@-128 {{previously declared 'read_only' here}} kernel void image_wo_twice(write_only __write_only image1d_t i){} // expected-warning {{duplicate '__write_only' declaration specifier}} kernel void image_wo_twice_typedef(write_only img1d_wo i){} // expected-warning {{duplicate 'write_only' declaration specifier}} -// expected-note@-103 {{previously declared 'write_only' here}} - +// expected-note@-130 {{previously declared 'write_only' here}}