forked from OSchip/llvm-project
[OpenCL] Fix access qualifiers handling for typedefs
OpenCL s6.6: "Access qualifier must be used with image object arguments of kernels and of user-defined functions [...] If no qualifier is provided, read_only is assumed". This does not define the behavior for image types used in typedef declaration, but following the spec logic, we should allow access qualifiers specification in typedefs, e.g.: typedef write_only image1d_t img1d_wo; Unlike cv-qualifiers, user cannot add access qualifier to a typedef type, i.e. this is not allowed: typedef image1d_t img1d; // note: previously declared 'read_only' here void foo(write_only img1d im) {} // error: multiple access qualifier Patch by Andrew Savonichev. Reviewers: Anastasia Stulova. Differential revision: http://reviews.llvm.org/D20948 llvm-svn: 274858
This commit is contained in:
parent
318d35a7bc
commit
c813c8113d
|
@ -688,7 +688,8 @@ def OpenCLAccess : Attr {
|
||||||
let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
|
let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
|
||||||
Keyword<"__write_only">, Keyword<"write_only">,
|
Keyword<"__write_only">, Keyword<"write_only">,
|
||||||
Keyword<"__read_write">, Keyword<"read_write">];
|
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">,
|
let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
|
||||||
Keyword<"read_only">]>,
|
Keyword<"read_only">]>,
|
||||||
Accessor<"isReadWrite", [Keyword<"__read_write">,
|
Accessor<"isReadWrite", [Keyword<"__read_write">,
|
||||||
|
|
|
@ -2506,8 +2506,8 @@ def warn_attribute_wrong_decl_type : Warning<
|
||||||
"variables and functions|functions and methods|parameters|"
|
"variables and functions|functions and methods|parameters|"
|
||||||
"functions, methods and blocks|functions, methods, and classes|"
|
"functions, methods and blocks|functions, methods, and classes|"
|
||||||
"functions, methods, and parameters|classes|enums|variables|methods|"
|
"functions, methods, and parameters|classes|enums|variables|methods|"
|
||||||
"fields and global variables|structs|variables and typedefs|thread-local variables|"
|
"fields and global variables|structs|parameters and typedefs|variables and typedefs|"
|
||||||
"variables and fields|variables, data members and tag types|"
|
"thread-local variables|variables and fields|variables, data members and tag types|"
|
||||||
"types and namespaces|Objective-C interfaces|methods and properties|"
|
"types and namespaces|Objective-C interfaces|methods and properties|"
|
||||||
"struct or union|struct, union or class|types|"
|
"struct or union|struct, union or class|types|"
|
||||||
"Objective-C instance methods|init methods of interface or class extension declarations|"
|
"Objective-C instance methods|init methods of interface or class extension declarations|"
|
||||||
|
@ -7923,9 +7923,11 @@ def err_opencl_builtin_pipe_invalid_access_modifier : Error<
|
||||||
def err_opencl_invalid_access_qualifier : Error<
|
def err_opencl_invalid_access_qualifier : Error<
|
||||||
"access qualifier can only be used for pipe and image type">;
|
"access qualifier can only be used for pipe and image type">;
|
||||||
def err_opencl_invalid_read_write : Error<
|
def err_opencl_invalid_read_write : Error<
|
||||||
"access qualifier %0 can not be used for %1 %select{|earlier than OpenCL version 2.0}2">;
|
"access qualifier %0 can not be used for %1 %select{|prior to OpenCL version 2.0}2">;
|
||||||
def err_opencl_multiple_access_qualifiers : Error<
|
def err_opencl_multiple_access_qualifiers : Error<
|
||||||
"multiple access qualifiers">;
|
"multiple access qualifiers">;
|
||||||
|
def note_opencl_typedef_access_qualifier : Note<
|
||||||
|
"previously declared '%0' here">;
|
||||||
|
|
||||||
// OpenCL Section 6.8.g
|
// OpenCL Section 6.8.g
|
||||||
def err_opencl_unknown_type_specifier : Error<
|
def err_opencl_unknown_type_specifier : Error<
|
||||||
|
|
|
@ -880,6 +880,7 @@ enum AttributeDeclKind {
|
||||||
ExpectedMethod,
|
ExpectedMethod,
|
||||||
ExpectedFieldOrGlobalVar,
|
ExpectedFieldOrGlobalVar,
|
||||||
ExpectedStruct,
|
ExpectedStruct,
|
||||||
|
ExpectedParameterOrTypedef,
|
||||||
ExpectedVariableOrTypedef,
|
ExpectedVariableOrTypedef,
|
||||||
ExpectedTLSVar,
|
ExpectedTLSVar,
|
||||||
ExpectedVariableOrField,
|
ExpectedVariableOrField,
|
||||||
|
|
|
@ -6481,12 +6481,31 @@ static void HandleNeonVectorTypeAttr(QualType& CurType,
|
||||||
/// Handle OpenCL Access Qualifier Attribute.
|
/// Handle OpenCL Access Qualifier Attribute.
|
||||||
static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr,
|
static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr,
|
||||||
Sema &S) {
|
Sema &S) {
|
||||||
// OpenCL v2.0 s6.6 - Access qualifier can used only for image and pipe type.
|
// OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe type.
|
||||||
if (!(CurType->isImageType() || CurType->isPipeType())) {
|
if (!(CurType->isImageType() || CurType->isPipeType())) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier);
|
S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier);
|
||||||
Attr.setInvalid();
|
Attr.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const TypedefType* TypedefTy = CurType->getAs<TypedefType>()) {
|
||||||
|
QualType PointeeTy = TypedefTy->desugar();
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
|
||||||
|
|
||||||
|
std::string PrevAccessQual;
|
||||||
|
switch (cast<BuiltinType>(PointeeTy.getTypePtr())->getKind()) {
|
||||||
|
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||||
|
case BuiltinType::Id: \
|
||||||
|
PrevAccessQual = #Access; \
|
||||||
|
break;
|
||||||
|
#include "clang/Basic/OpenCLImageTypes.def"
|
||||||
|
default:
|
||||||
|
assert(0 && "Unable to find corresponding image type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
S.Diag(TypedefTy->getDecl()->getLocStart(),
|
||||||
|
diag::note_opencl_typedef_access_qualifier) << PrevAccessQual;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
||||||
|
|
|
@ -49,7 +49,7 @@ kernel void foo4(__global unsigned int * X, __global myunsignedint * Y) {
|
||||||
// ARGINFO: !kernel_arg_name ![[MD46:[0-9]+]]
|
// ARGINFO: !kernel_arg_name ![[MD46:[0-9]+]]
|
||||||
|
|
||||||
typedef image1d_t myImage;
|
typedef image1d_t myImage;
|
||||||
kernel void foo5(read_only myImage img1, write_only image1d_t img2) {
|
kernel void foo5(myImage img1, write_only image1d_t img2) {
|
||||||
}
|
}
|
||||||
// CHECK: define spir_kernel void @foo5{{[^!]+}}
|
// CHECK: define spir_kernel void @foo5{{[^!]+}}
|
||||||
// CHECK: !kernel_arg_addr_space ![[MD41:[0-9]+]]
|
// CHECK: !kernel_arg_addr_space ![[MD41:[0-9]+]]
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL1.2 %s
|
||||||
|
// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s
|
||||||
|
|
||||||
|
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
|
||||||
|
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); // 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}}
|
||||||
|
|
||||||
|
#if __OPENCL_C_VERSION__ >= 200
|
||||||
|
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 version 2.0}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __OPENCL_C_VERSION__ >= 200
|
||||||
|
kernel void k4(img1d_rw img) {
|
||||||
|
myReadWrite(img);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
kernel void k5(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 k6(img1d_ro img) {
|
||||||
|
myRead(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel void k7(read_only img1d_wo img){} // expected-error {{multiple access qualifiers}}
|
||||||
|
|
||||||
|
kernel void k8(write_only img1d_ro_default img){} // expected-error {{multiple access qualifiers}}
|
||||||
|
|
||||||
|
kernel void k9(read_only int i){} // expected-error{{access qualifier can only be used for pipe and image type}}
|
||||||
|
|
||||||
|
kernel void k10(read_only Int img){} // expected-error {{access qualifier can only be used for pipe and image type}}
|
||||||
|
|
||||||
|
kernel void k11(read_only write_only image1d_t i){} // expected-error{{multiple access qualifiers}}
|
||||||
|
|
||||||
|
kernel void k12(read_only read_only image1d_t i){} // expected-error{{multiple access qualifiers}}
|
||||||
|
|
||||||
|
#if __OPENCL_C_VERSION__ >= 200
|
||||||
|
kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for '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 version 2.0}}
|
||||||
|
#endif
|
|
@ -1,14 +0,0 @@
|
||||||
// RUN: %clang_cc1 -verify %s
|
|
||||||
// RUN: %clang_cc1 -verify -cl-std=CL2.0 -DCL20 %s
|
|
||||||
|
|
||||||
void test1(read_only int i){} // expected-error{{access qualifier can only be used for pipe and image type}}
|
|
||||||
|
|
||||||
void test2(read_only write_only image1d_t i){} // expected-error{{multiple access qualifiers}}
|
|
||||||
|
|
||||||
void test3(read_only read_only image1d_t i){} // expected-error{{multiple access qualifiers}}
|
|
||||||
|
|
||||||
#ifdef CL20
|
|
||||||
void test4(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'pipe int'}}
|
|
||||||
#else
|
|
||||||
void test4(__read_write image1d_t i) {} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' earlier than OpenCL version 2.0}}
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue