1*67e74705SXin Li// RUN: %clang_cc1 -verify -fblocks -cl-std=CL2.0 %s 2*67e74705SXin Li 3*67e74705SXin Li// OpenCL v2.0 s6.12.5 4*67e74705SXin Livoid f0(int (^const bl)()); 5*67e74705SXin Li// All blocks declarations must be const qualified and initialized. 6*67e74705SXin Livoid f1() { 7*67e74705SXin Li int (^bl1)() = ^() {return 1;}; 8*67e74705SXin Li int (^const bl2)() = ^(){return 1;}; 9*67e74705SXin Li f0(bl1); 10*67e74705SXin Li f0(bl2); 11*67e74705SXin Li bl1 = bl2; // expected-error{{invalid operands to binary expression ('int (^const)()' and 'int (^const)()')}} 12*67e74705SXin Li int (^const bl3)(); // expected-error{{invalid block variable declaration - must be initialized}} 13*67e74705SXin Li} 14*67e74705SXin Li 15*67e74705SXin Li// A block with extern storage class is not allowed. 16*67e74705SXin Liextern int (^bl)() = ^(){return 1;}; // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}} 17*67e74705SXin Livoid f2() { 18*67e74705SXin Li extern int (^bl)() = ^(){return 1;}; // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}} 19*67e74705SXin Li} 20*67e74705SXin Li 21*67e74705SXin Li// A block cannot be the return value of a function. 22*67e74705SXin Litypedef int (^bl_t)(void); 23*67e74705SXin Libl_t f3(bl_t bl); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (^const)(void)') is not allowed}} 24*67e74705SXin Li 25*67e74705SXin Listruct bl_s { 26*67e74705SXin Li int (^bl)(void); // expected-error {{the 'int (^const)(void)' type cannot be used to declare a structure or union field}} 27*67e74705SXin Li}; 28*67e74705SXin Li 29*67e74705SXin Livoid f4() { 30*67e74705SXin Li __block int a = 10; // expected-error {{the __block storage type is not permitted}} 31*67e74705SXin Li} 32*67e74705SXin Li 33*67e74705SXin Li// A block with variadic argument is not allowed. 34*67e74705SXin Liint (^bl)(int, ...) = ^int(int I, ...) { // expected-error {{invalid block prototype, variadic arguments are not allowed in OpenCL}} 35*67e74705SXin Li return 0; 36*67e74705SXin Li}; 37*67e74705SXin Li 38*67e74705SXin Li// A block can't be used to declare an array 39*67e74705SXin Litypedef int (^bl1_t)(int); 40*67e74705SXin Livoid f5(int i) { 41*67e74705SXin Li bl1_t bl1 = ^(int i) {return 1;}; 42*67e74705SXin Li bl1_t bl2 = ^(int i) {return 2;}; 43*67e74705SXin Li bl1_t arr[] = {bl1, bl2}; // expected-error {{array of 'bl1_t' (aka 'int (^const)(int)') type is invalid in OpenCL}} 44*67e74705SXin Li int tmp = i ? bl1(i) // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}} 45*67e74705SXin Li : bl2(i); // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}} 46*67e74705SXin Li} 47*67e74705SXin Li// A block pointer type and all pointer operations are disallowed 48*67e74705SXin Livoid f6(bl1_t * bl_ptr) { // expected-error{{pointer to type '__generic bl1_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} 49*67e74705SXin Li bl1_t bl = ^(int i) {return 1;}; 50*67e74705SXin Li bl1_t *p; // expected-error {{pointer to type '__generic bl1_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} 51*67e74705SXin Li *bl; // expected-error {{invalid argument type 'bl1_t' (aka 'int (^const)(int)') to unary expression}} 52*67e74705SXin Li &bl; // expected-error {{invalid argument type 'bl1_t' (aka 'int (^const)(int)') to unary expression}} 53*67e74705SXin Li} 54