Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -685,7 +685,8 @@ let Spellings = [Keyword<"__read_only">, Keyword<"read_only">, Keyword<"__write_only">, Keyword<"write_only">, Keyword<"__read_write">, Keyword<"read_write">]; - let Subjects = SubjectList<[ParmVar], ErrorDiag>; + let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag, + "ExpectedParameterOrTypedef">; let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">, Keyword<"read_only">]>, Accessor<"isReadWrite", [Keyword<"__read_write">, Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2496,8 +2496,8 @@ "variables and functions|functions and methods|parameters|" "functions, methods and blocks|functions, methods, and classes|" "functions, methods, and parameters|classes|enums|variables|methods|" - "fields and global variables|structs|variables and typedefs|thread-local variables|" - "variables and fields|variables, data members and tag types|" + "fields and global variables|structs|parameters and typedefs|variables and typedefs|" + "thread-local variables|variables and fields|variables, data members and tag types|" "types and namespaces|Objective-C interfaces|methods and properties|" "struct or union|struct, union or class|types|" "Objective-C instance methods|init methods of interface or class extension declarations|" @@ -7879,6 +7879,9 @@ "access qualifier %0 can not be used for %1 %select{|earlier than OpenCL version 2.0}2">; def err_opencl_multiple_access_qualifiers : Error< "multiple access qualifiers">; +def warn_default_access_qualifier : Warning< + "missing access qualifier: assuming read_only">, + InGroup>; // OpenCL Section 6.8.g def err_opencl_unknown_type_specifier : Error< Index: include/clang/Sema/AttributeList.h =================================================================== --- include/clang/Sema/AttributeList.h +++ include/clang/Sema/AttributeList.h @@ -881,6 +881,7 @@ ExpectedMethod, ExpectedFieldOrGlobalVar, ExpectedStruct, + ExpectedParameterOrTypedef, ExpectedVariableOrTypedef, ExpectedTLSVar, ExpectedVariableOrField, Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1626,8 +1626,13 @@ Result = llvm::StringSwitch( \ getImageAccessAttrStr(DS.getAttributes().getList())) \ .Cases("write_only", "__write_only", Context.Id##WOTy) \ + .Cases("read_only", "__read_only", Context.Id##ROTy) \ .Cases("read_write", "__read_write", Context.Id##RWTy) \ - .Default(Context.Id##ROTy); \ + .Default(QualType()); \ + if (Result.isNull()) { \ + Result = Context.Id##ROTy; \ + S.Diag(DS.getTypeSpecTypeLoc(), diag::warn_default_access_qualifier);\ + } \ break; #include "clang/Basic/OpenCLImageTypes.def" @@ -6473,7 +6478,8 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr, Sema &S) { // OpenCL v2.0 s6.6 - Access qualifier can used only for image and pipe type. - if (!(CurType->isImageType() || CurType->isPipeType())) { + if (!(CurType->isImageType() || CurType->isPipeType()) || + isa(CurType)) { S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier); Attr.setInvalid(); return; Index: test/CodeGenOpenCL/kernel-arg-info.cl =================================================================== --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -45,8 +45,8 @@ // ARGINFO: !{!"kernel_arg_name", !"X", !"Y"} // NO-ARGINFO-NOT: !{!"kernel_arg_name", !"X", !"Y"} -typedef image1d_t myImage; -kernel void foo5(read_only myImage img1, write_only image1d_t img2) { +typedef read_only image1d_t myImage; +kernel void foo5(myImage img1, write_only image1d_t img2) { } // CHECK: !{!"kernel_arg_access_qual", !"read_only", !"write_only"} // CHECK: !{!"kernel_arg_type", !"myImage", !"image1d_t"} Index: test/SemaOpenCL/images-typedef.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/images-typedef.cl @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +typedef image1d_t img1d_ro_default; // expected-warning {{missing access qualifier: assuming read_only}} + +typedef write_only image1d_t img1d_wo; +typedef read_only image1d_t img1d_ro; +typedef read_write image1d_t img1d_rw; + +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); // 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}} + +kernel void k1 (img1d_wo img) { + myRead(img); // expected-error {{passing 'img1d_wo' (aka '__write_only image1d_t') to parameter of incompatible type '__read_only image1d_t'}} +} + +kernel void k2 (img1d_ro img) { + myWrite(img); // expected-error {{passing 'img1d_ro' (aka '__read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} +} + +kernel void k3 (img1d_wo img) { + myWrite(img); +} + +kernel void k4 (img1d_ro_default img) { + myWrite(img); // expected-error {{passing 'img1d_ro_default' (aka '__read_only image1d_t') to parameter of incompatible type '__write_only image1d_t'}} +} + +kernel void k5 (img1d_ro img) { + myRead(img); +} + +kernel void k6 (read_only img1d_wo img) { // expected-error {{access qualifier can only be used for pipe and image type}} +} + +kernel void k7 (write_only img1d_ro_default img) { // expected-error {{access qualifier can only be used for pipe and image type}} +} + +kernel void k8 (read_only int img) { // expected-error {{access qualifier can only be used for pipe and image type}} +} + +kernel void k9 (read_only Int img) { // expected-error {{access qualifier can only be used for pipe and image type}} +} + +kernel void k10() { + write_only int i; // expected-error {{access qualifier can only be used for pipe and image type}} +} Index: test/SemaOpenCL/images.cl =================================================================== --- test/SemaOpenCL/images.cl +++ test/SemaOpenCL/images.cl @@ -2,7 +2,7 @@ void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} -void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { +void imgage_access_test(read_only image2d_t img2dro, write_only image2d_t img2dwo, read_only image3d_t img3dro) { img2d_ro(img2dro); img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} Index: test/SemaOpenCL/invalid-image.cl =================================================================== --- test/SemaOpenCL/invalid-image.cl +++ test/SemaOpenCL/invalid-image.cl @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -verify %s -void test1(image1d_t *i) {} // expected-error {{pointer to type '__read_only image1d_t' is invalid in OpenCL}} +void test1(read_only image1d_t *i) {} // expected-error {{pointer to type '__read_only image1d_t' is invalid in OpenCL}} -void test2(image1d_t i) { - image1d_t ti; // expected-error {{type '__read_only image1d_t' can only be used as a function parameter}} - image1d_t ai[] = {i, i}; // expected-error {{array of '__read_only image1d_t' type is invalid in OpenCL}} +void test2(read_only image1d_t i) { + read_only image1d_t ti; // expected-error {{type '__read_only image1d_t' can only be used as a function parameter}} + read_only image1d_t ai[] = {i, i}; // expected-error {{array of '__read_only image1d_t' type is invalid in OpenCL}} expected-error {{'read_only' attribute only applies to parameters and typedefs}} } Index: test/SemaOpenCL/invalid-kernel-attrs.cl =================================================================== --- test/SemaOpenCL/invalid-kernel-attrs.cl +++ test/SemaOpenCL/invalid-kernel-attrs.cl @@ -26,7 +26,7 @@ constant int foo3 __attribute__((vec_type_hint(char))) = 0; // expected-error {{'vec_type_hint' attribute only applies to functions}} -void f_kernel_image2d_t( kernel image2d_t image ) { // expected-error {{'kernel' attribute only applies to functions}} +void f_kernel_image2d_t( kernel image2d_t image ) { // expected-error {{'kernel' attribute only applies to functions}} expected-warning {{missing access qualifier: assuming read_only}} int __kernel x; // expected-error {{'__kernel' attribute only applies to functions}} } Index: test/SemaOpenCL/invalid-kernel-parameters.cl =================================================================== --- test/SemaOpenCL/invalid-kernel-parameters.cl +++ test/SemaOpenCL/invalid-kernel-parameters.cl @@ -27,7 +27,7 @@ // 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-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}} expected-warning {{missing access qualifier: assuming read_only}} } FooImage2D; kernel void image_in_struct_arg(FooImage2D arg) { } // expected-error{{struct kernel parameters may not contain pointers}}