1 // RUN: %clang_cc1 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -pedantic -fsyntax-only %s -verify -fblocks 2 // RUN: %clang_cc1 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -pedantic -fsyntax-only %s -verify -fblocks -fexperimental-new-constant-interpreter 3 4 extern int printf(const char *, ...); 5 6 typedef void (^CL)(void); 7 8 CL foo(void) { 9 short y; 10 short (^add1)(void) = ^{ return y+1; }; // expected-error {{incompatible block pointer types initializing 'short (^)(void)' with an expression of type 'int (^)(void)'}} 11 12 CL X = ^{ 13 if (2) 14 return; 15 return 1; // expected-error {{return type 'int' must match previous return type 'void' when block literal has unspecified explicit return type}} 16 }; 17 18 int (^Y) (void) = ^{ 19 if (3) 20 return 1; 21 else 22 return; // expected-error {{return type 'void' must match previous return type 'int' when block literal has unspecified explicit return type}} 23 }; 24 25 char *(^Z)(void) = ^{ 26 if (3) 27 return ""; 28 else 29 return (char*)0; 30 }; 31 32 double (^A)(void) = ^ { // expected-error {{incompatible block pointer types initializing 'double (^)(void)' with an expression of type 'float (^)(void)'}} 33 if (1) 34 return (float)1.0; 35 else 36 if (2) 37 return (double)2.0; // expected-error {{return type 'double' must match previous return type 'float' when block literal has unspecified explicit return type}} 38 return 1; // expected-error {{return type 'int' must match previous return type 'float' when block literal has unspecified explicit return type}} 39 }; 40 char *(^B)(void) = ^{ 41 if (3) 42 return ""; 43 else 44 return 2; // expected-error {{return type 'int' must match previous return type 'char *' when block literal has unspecified explicit return type}} 45 }; 46 47 return ^{ return 1; }; // expected-error {{incompatible block pointer types returning 'int (^)(void)' from a function with result type 'CL' (aka 'void (^)(void)')}} 48 } 49 50 typedef int (^CL2)(void); 51 52 CL2 foo2(void) { 53 return ^{ return 1; }; 54 } 55 56 typedef unsigned int * uintptr_t; 57 typedef char Boolean; 58 typedef int CFBasicHash; 59 60 #define INVOKE_CALLBACK2(P, A, B) (P)(A, B) 61 62 typedef struct { 63 Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key); 64 } CFBasicHashCallbacks; 65 66 int foo3(void) { 67 CFBasicHashCallbacks cb; 68 69 Boolean (*value_equal)(uintptr_t, uintptr_t) = 0; 70 71 cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) { 72 return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2); 73 }; 74 } 75 76 static int funk(char *s) { 77 if (^{} == ((void*)0)) 78 return 1; 79 else 80 return 0; 81 } 82 void next(void); 83 void foo4(void) { 84 int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-error {{incompatible block pointer types initializing 'int (^)(const char *)' with an expression of type 'int (^)(char *)'}} 85 int (*yy)(const char *s) = funk; // expected-error {{incompatible function pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}} 86 87 int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; }; 88 } 89 90 typedef void (^bptr)(void); 91 92 bptr foo5(int j) { 93 __block int i; 94 if (j) 95 return ^{ ^{ i=0; }(); }; // expected-error {{returning block that lives on the local stack}} 96 return ^{ i=0; }; // expected-error {{returning block that lives on the local stack}} 97 return (^{ i=0; }); // expected-error {{returning block that lives on the local stack}} 98 return (void*)(^{ i=0; }); // expected-error {{returning block that lives on the local stack}} 99 } 100 101 int (*funcptr3[5])(long); 102 int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block cannot return array type}} expected-error {{incompatible pointer to integer conversion}} 103 int sz9 = sizeof(^int(*())()[3]{ }); // expected-error {{function cannot return array type}} 104 // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}} 105 106 void foo6(void) { 107 int (^b)(int) __attribute__((noreturn)); 108 b = ^ (int i) __attribute__((noreturn)) { return 1; }; // expected-error {{block declared 'noreturn' should not return}} 109 b(1); 110 int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}} 111 } 112 113 114 void foo7(void) 115 { 116 const int (^BB) (void) = ^{ const int i = 1; return i; }; // OK - initializing 'const int (^)(void)' with an expression of type 'int (^)(void)' 117 118 const int (^CC) (void) = ^const int{ const int i = 1; return i; }; 119 120 121 int i; 122 int (^FF) (void) = ^{ return i; }; // OK 123 int (^EE) (void) = ^{ return i+1; }; // OK 124 125 __block int j; 126 int (^JJ) (void) = ^{ return j; }; // OK 127 int (^KK) (void) = ^{ return j+1; }; // OK 128 129 __block const int k; 130 const int cint = 100; 131 132 int (^MM) (void) = ^{ return k; }; 133 int (^NN) (void) = ^{ return cint; }; 134 } 135 136 void (^blk)(void) = ^{ 137 return (void)0; // expected-warning {{void block literal should not return void expression}} 138 }; 139 140 enum Test8 { T8_a, T8_b, T8_c }; 141 void test8(void) { 142 extern void test8_helper(int (^)(int)); 143 test8_helper(^(int flag) { if (flag) return T8_a; return T8_b; }); 144 } 145 void test8b(void) { 146 extern void test8_helper2(char (^)(int)); // expected-note {{here}} 147 test8_helper2(^(int flag) { if (flag) return T8_a; return T8_b; }); // expected-error {{passing 'enum Test8 (^)(int)' to parameter of type 'char (^)(int)'}} 148 } 149