forked from OSchip/llvm-project
[OpenCL] Reject block arguments
OpenCL 2.0 does not allow block arguments, primarily because it is difficult to support function pointers on the various architectures that OpenCL targets. Clang was still accepting them. Rename and reuse the `err_opencl_half_param` diagnostic. Fixes PR46324. Differential Revision: https://reviews.llvm.org/D82313
This commit is contained in:
parent
b7ca06b745
commit
bd46a56474
|
@ -830,8 +830,8 @@ def err_opencl_half_load_store : Error<
|
|||
def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
|
||||
def err_opencl_half_declaration : Error<
|
||||
"declaring variable of type %0 is not allowed">;
|
||||
def err_opencl_half_param : Error<
|
||||
"declaring function parameter of type %0 is not allowed; did you forget * ?">;
|
||||
def err_opencl_invalid_param : Error<
|
||||
"declaring function parameter of type %0 is not allowed%select{; did you forget * ?|}1">;
|
||||
def err_opencl_invalid_return : Error<
|
||||
"declaring function return value of type %0 is not allowed %select{; did you forget * ?|}1">;
|
||||
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
|
||||
|
|
|
@ -5139,8 +5139,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
// FIXME: This really should be in BuildFunctionType.
|
||||
if (S.getLangOpts().OpenCL) {
|
||||
if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
|
||||
S.Diag(Param->getLocation(),
|
||||
diag::err_opencl_half_param) << ParamTy;
|
||||
S.Diag(Param->getLocation(), diag::err_opencl_invalid_param)
|
||||
<< ParamTy << 0;
|
||||
D.setInvalidType();
|
||||
Param->setInvalidDecl();
|
||||
}
|
||||
|
@ -5159,6 +5159,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
Param->setKNRPromoted(true);
|
||||
}
|
||||
}
|
||||
} else if (S.getLangOpts().OpenCL && ParamTy->isBlockPointerType()) {
|
||||
// OpenCL 2.0 s6.12.5: A block cannot be a parameter of a function.
|
||||
S.Diag(Param->getLocation(), diag::err_opencl_invalid_param)
|
||||
<< ParamTy << 1 /*hint off*/;
|
||||
D.setInvalidType();
|
||||
}
|
||||
|
||||
if (LangOpts.ObjCAutoRefCount && Param->hasAttr<NSConsumedAttr>()) {
|
||||
|
|
|
@ -70,26 +70,6 @@ void foo(){
|
|||
|
||||
// COMMON-NOT: define{{.*}}@__foo_block_invoke_kernel
|
||||
|
||||
// Test that we support block arguments.
|
||||
// COMMON-LABEL: define {{.*}} @blockArgFunc
|
||||
int blockArgFunc(int (^ bl)(void)) {
|
||||
return bl();
|
||||
}
|
||||
|
||||
// COMMON-LABEL: define {{.*}} @get21
|
||||
// COMMON: define {{.*}} @__get21_block_invoke
|
||||
// COMMON: ret i32 21
|
||||
int get21() {
|
||||
return blockArgFunc(^{return 21;});
|
||||
}
|
||||
|
||||
// COMMON-LABEL: define {{.*}} @get42
|
||||
// COMMON: define {{.*}} @__get42_block_invoke
|
||||
// COMMON: ret i32 42
|
||||
int get42() {
|
||||
return blockArgFunc(^{return 42;});
|
||||
}
|
||||
|
||||
// COMMON-LABEL: define {{.*}}@call_block
|
||||
// call {{.*}}@__call_block_block_invoke
|
||||
int call_block() {
|
||||
|
|
|
@ -21,7 +21,7 @@ int member;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
void f(void (^g)(void)) {
|
||||
typedef int (^bl_t)(void);
|
||||
#if defined(__OPENCL_C_VERSION__) || defined(__OPENCL_CPP_VERSION__)
|
||||
#if !defined(BLOCKS) && (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ != CL_VERSION_2_0)
|
||||
// expected-error@-3{{blocks support disabled - compile with -fblocks or for OpenCL 2.0}}
|
||||
|
@ -29,7 +29,6 @@ void f(void (^g)(void)) {
|
|||
#else
|
||||
// expected-error@-6{{blocks support disabled - compile with -fblocks or pick a deployment target that supports them}}
|
||||
#endif
|
||||
}
|
||||
|
||||
// CHECK-INVALID-OPENCL-VERSION11: warning: OpenCL version 1.1 does not support the option '-cl-strict-aliasing'
|
||||
// CHECK-INVALID-OPENCL-VERSION12: warning: OpenCL version 1.2 does not support the option '-cl-strict-aliasing'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// RUN: %clang_cc1 -verify -fblocks -cl-std=CL2.0 %s
|
||||
|
||||
// OpenCL v2.0 s6.12.5
|
||||
void f0(int (^const bl)());
|
||||
void f0(int (^const bl)()); // expected-error{{declaring function parameter of type 'int (__generic ^const __private)(void)' is not allowed}}
|
||||
// All blocks declarations must be const qualified and initialized.
|
||||
void f1() {
|
||||
int (^bl1)(void) = ^() {
|
||||
|
@ -26,9 +26,18 @@ void f2() {
|
|||
};
|
||||
}
|
||||
|
||||
// A block cannot be the return value of a function.
|
||||
// A block cannot be the return value or parameter of a function.
|
||||
typedef int (^bl_t)(void);
|
||||
bl_t f3(bl_t bl); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}}
|
||||
bl_t f3a(int); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}}
|
||||
bl_t f3b(bl_t bl);
|
||||
// expected-error@-1{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}}
|
||||
// expected-error@-2{{declaring function parameter of type '__private bl_t' (aka 'int (__generic ^const __private)(void)') is not allowed}}
|
||||
void f3c() {
|
||||
// Block with a block argument.
|
||||
int (^const bl2)(bl_t block_arg) = ^() { // expected-error{{declaring function parameter of type '__private bl_t' (aka 'int (__generic ^const __private)(void)') is not allowed}}
|
||||
return block_arg(); // expected-error{{implicit declaration of function 'block_arg' is invalid in OpenCL}}
|
||||
};
|
||||
}
|
||||
|
||||
struct bl_s {
|
||||
int (^bl)(void); // expected-error {{the 'int (__generic ^const)(void)' type cannot be used to declare a structure or union field}}
|
||||
|
|
Loading…
Reference in New Issue