blob: a3b9562ee9def48a3b4239136cb3dc8bbcf64688 [file] [log] [blame]
Steve Naroff3eac7692008-09-10 19:17:48 +00001// 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