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