block-literal.c revision 61f40a2b67fc2046768e14f66b617e564cbcc3d8
1// RUN: clang -fsyntax-only %s -verify 2 3void I( void (^)(void)); 4void (^noop)(void); 5 6void nothing(); 7int printf(const char*, ...); 8 9typedef void (^T) (void); 10 11void takeclosure(T); 12int takeintint(int (^C)(int)) { return C(4); } 13 14T somefunction() { 15 if (^{ }) 16 nothing(); 17 18 noop = ^{}; 19 20 noop = ^{printf("\nClosure\n"); }; 21 22 I(^{ }); 23 24 noop = ^noop; // expected-error {{incompatible block pointer types}} 25 26 return ^{printf("\nClosure\n"); }; // expected-error {{returning block that lives on the local stack}} 27} 28void test2() { 29 int x = 4; 30 31 takeclosure(^{ printf("%d\n", x); }); 32 33 while (1) { 34 takeclosure(^{ 35 break; // expected-error {{'break' statement not in loop or switch statement}} 36 continue; // expected-error {{'continue' statement not in loop statement}} 37 while(1) break; // ok 38 goto foo; // expected-error {{goto not allowed}} 39 }); 40 break; 41 } 42 43foo: 44 takeclosure(^{ x = 4; }); // expected-error {{expression is not assignable}} 45 46 takeclosure(^test2()); 47 takeclosure(^(void)(void)printf("hello world!\n")); 48 49} 50 51 52void (^test3())(void) { 53 return ^{}; // expected-error {{returning block that lives on the local stack}} 54} 55 56void test4() { 57 void (^noop)(void) = ^{}; 58 void (*noop2)() = 0; 59} 60 61void *X; 62 63void test_arguments() { 64 takeintint(^(int x)(x+1)); 65 66 // Closure expr of statement expr. 67 takeintint(^(int x)({ return 42; })); // expected-error {{return not allowed in block expression literal}} 68 69 int y; 70 takeintint(^(int x)(x+y)); 71#if 0 72 // FIXME: this causes clang to crash. 73 X = ^(x+r); // expected-error {{expected ')' in argument list}} 74#endif 75 int (^c)(char); 76 (1 ? c : 0)('x'); 77 (1 ? 0 : c)('x'); 78 79 (1 ? c : c)('x'); 80} 81 82#if 0 83// Old syntax. FIXME: convert/test. 84void test_byref() { 85 int i; 86 87 X = ^{| g |}; // expected-error {{use of undeclared identifier 'g'}} 88 89 X = ^{| i,i,i | }; 90 91 X = ^{|i| i = 0; }; 92 93} 94 95// TODO: global closures someday. 96void *A = ^{}; 97void *B = ^(int){ A = 0; }; 98 99 100// Closures can not take return types at this point. 101void test_retvals() { 102 // Explicit return value. 103 ^int{}; // expected-error {{closure with explicit return type requires argument list}} 104 X = ^void(){}; 105 106 // Optional specification of return type. 107 X = ^char{ return 'x'; }; // expected-error {{closure with explicit return type requires argument list}} 108 109 X = ^/*missing declspec*/ *() { return (void*)0; }; 110 X = ^void*() { return (void*)0; }; 111 112 //X = ^char(short c){ if (c) return c; else return (int)4; }; 113 114} 115 116#endif 117