150
|
1 // RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
|
|
2 void donotwarn();
|
|
3
|
|
4 int (^IFP) ();
|
|
5 int (^II) (int);
|
|
6 int test1() {
|
|
7 int (^PFR) (int) = 0; // OK
|
|
8 PFR = II; // OK
|
|
9
|
|
10 if (PFR == II) // OK
|
|
11 donotwarn();
|
|
12
|
|
13 if (PFR == IFP) // OK
|
|
14 donotwarn();
|
|
15
|
|
16 if (PFR == (int (^) (int))IFP) // OK
|
|
17 donotwarn();
|
|
18
|
|
19 if (PFR == 0) // OK
|
|
20 donotwarn();
|
|
21
|
|
22 if (PFR) // OK
|
|
23 donotwarn();
|
|
24
|
|
25 if (!PFR) // OK
|
|
26 donotwarn();
|
|
27
|
|
28 return PFR != IFP; // OK
|
|
29 }
|
|
30
|
|
31 int test2(double (^S)()) {
|
|
32 double (^I)(int) = (void*) S;
|
|
33 (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
|
|
34
|
|
35 void *pv = I;
|
|
36
|
|
37 pv = S;
|
|
38
|
|
39 I(1);
|
|
40
|
|
41 return (void*)I == (void *)S;
|
|
42 }
|
|
43
|
|
44 int^ x; // expected-error {{block pointer to non-function type is invalid}}
|
|
45 int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
|
|
46
|
|
47 void test3() {
|
|
48 char *^ y; // expected-error {{block pointer to non-function type is invalid}}
|
|
49 }
|
|
50
|
|
51
|
|
52
|
|
53 enum {NSBIRLazilyAllocated = 0};
|
|
54
|
|
55 int test4(int argc) { // rdar://6251437
|
|
56 ^{
|
|
57 switch (argc) {
|
|
58 case NSBIRLazilyAllocated: // is an integer constant expression.
|
|
59 default:
|
|
60 break;
|
|
61 }
|
|
62 }();
|
|
63 return 0;
|
|
64 }
|
|
65
|
|
66
|
|
67 void bar(void*);
|
|
68 // rdar://6257721 - reference to static/global is byref by default.
|
|
69 static int test5g;
|
|
70 void test5() {
|
|
71 bar(^{ test5g = 1; });
|
|
72 }
|
|
73
|
|
74 // rdar://6405429 - __func__ in a block refers to the containing function name.
|
|
75 const char*test6() {
|
|
76 return ^{
|
|
77 return __func__;
|
|
78 } ();
|
|
79 }
|
|
80
|
|
81 // radr://6732116 - block comparisons
|
|
82 void (^test7a)();
|
|
83 int test7(void (^p)()) {
|
|
84 return test7a == p;
|
|
85 }
|
|
86
|
|
87
|
|
88 void test8() {
|
|
89 somelabel:
|
|
90 ^{ goto somelabel; }(); // expected-error {{use of undeclared label 'somelabel'}}
|
|
91 }
|
|
92
|
|
93 void test9() {
|
|
94 goto somelabel; // expected-error {{use of undeclared label 'somelabel'}}
|
|
95 ^{ somelabel: ; }();
|
|
96 }
|
|
97
|
|
98 void test10(int i) {
|
|
99 switch (i) {
|
|
100 case 41: ;
|
|
101 ^{ case 42: ; }(); // expected-error {{'case' statement not in switch statement}}
|
|
102 }
|
|
103 }
|
|
104
|
|
105 void test11(int i) {
|
|
106 switch (i) {
|
|
107 case 41: ;
|
|
108 ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}}
|
|
109 }
|
|
110
|
|
111 for (; i < 100; ++i)
|
|
112 ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}}
|
|
113 }
|
|
114
|
|
115 void (^test12f)(void);
|
|
116 void test12() {
|
|
117 test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}}
|
|
118 }
|
|
119
|
|
120 // rdar://6808730
|
|
121 void *test13 = ^{
|
|
122 int X = 32;
|
|
123
|
|
124 void *P = ^{
|
|
125 return X+4; // References outer block's "X", so outer block is constant.
|
|
126 };
|
|
127 };
|
|
128
|
|
129 void test14() {
|
|
130 int X = 32;
|
|
131 static void *P = ^{ // expected-error {{initializer element is not a compile-time constant}}
|
|
132
|
|
133 void *Q = ^{
|
|
134 // References test14's "X": outer block is non-constant.
|
|
135 return X+4;
|
|
136 };
|
|
137 };
|
|
138 }
|
|
139
|
|
140 enum { LESS };
|
|
141
|
|
142 void foo(long (^comp)()) { // expected-note{{passing argument to parameter 'comp' here}}
|
|
143 }
|
|
144
|
|
145 void (^test15f)(void);
|
|
146 void test15() {
|
|
147 foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)' to parameter of type 'long (^)()'}}
|
|
148 }
|
|
149
|
|
150 __block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}}
|
|
151
|
|
152 void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}}
|
|
153 int size = 5;
|
|
154 extern __block double extern_var; // expected-error {{__block attribute not allowed, only allowed on local variables}}
|
|
155 static __block char * pch; // expected-error {{__block attribute not allowed, only allowed on local variables}}
|
|
156 __block int a[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
|
|
157 __block int (*ap)[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
|
|
158 }
|
|
159
|
|
160 void f();
|
|
161
|
|
162 void test17() {
|
|
163 void (^bp)(int);
|
|
164 void (*rp)(int);
|
|
165 void (^bp1)();
|
|
166 void *vp = bp;
|
|
167
|
|
168 f(1 ? bp : vp);
|
|
169 f(1 ? vp : bp);
|
|
170 f(1 ? bp : bp1);
|
|
171 (void)(bp > rp); // expected-error {{invalid operands}}
|
|
172 (void)(bp > 0); // expected-error {{invalid operands}}
|
|
173 (void)(bp > bp); // expected-error {{invalid operands}}
|
|
174 (void)(bp > vp); // expected-error {{invalid operands}}
|
|
175 f(1 ? bp : rp); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (*)(int)')}}
|
|
176 (void)(bp == 1); // expected-error {{invalid operands to binary expression}}
|
|
177 (void)(bp == 0);
|
|
178 (void)(1 == bp); // expected-error {{invalid operands to binary expression}}
|
|
179 (void)(0 == bp);
|
|
180 (void)(bp < 1); // expected-error {{invalid operands to binary expression}}
|
|
181 (void)(bp < 0); // expected-error {{invalid operands to binary expression}}
|
|
182 (void)(1 < bp); // expected-error {{invalid operands to binary expression}}
|
|
183 (void)(0 < bp); // expected-error {{invalid operands to binary expression}}
|
|
184 }
|
|
185
|
|
186 void test18() {
|
|
187 void (^const blockA)(void) = ^{ }; // expected-note {{variable 'blockA' declared const here}}
|
|
188 blockA = ^{ }; // expected-error {{cannot assign to variable 'blockA' with const-qualified type 'void (^const)(void)}}
|
|
189 }
|
|
190
|
|
191 // rdar://7072507
|
|
192 int test19() {
|
|
193 goto L0; // expected-error {{cannot jump}}
|
|
194
|
|
195 __block int x; // expected-note {{jump bypasses setup of __block variable}}
|
|
196 L0:
|
|
197 x = 0;
|
|
198 ^(){ ++x; }();
|
|
199 return x;
|
|
200 }
|
|
201
|
|
202 // radr://7438948
|
|
203 void test20() {
|
|
204 int n = 7;
|
|
205 int vla[n]; // expected-note {{declared here}}
|
|
206 int (*vm)[n] = 0; // expected-note {{declared here}}
|
|
207 vla[1] = 4341;
|
|
208 ^{
|
|
209 (void)vla[1]; // expected-error {{cannot refer to declaration with a variably modified type inside block}}
|
|
210 (void)(vm+1); // expected-error {{cannot refer to declaration with a variably modified type inside block}}
|
|
211 }();
|
|
212 }
|
|
213
|
|
214 // radr://7438948
|
|
215 void test21() {
|
|
216 int a[7]; // expected-note {{declared here}}
|
|
217 __block int b[10]; // expected-note {{declared here}}
|
|
218 a[1] = 1;
|
|
219 ^{
|
|
220 (void)a[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
|
|
221 (void)b[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
|
|
222 }();
|
|
223 }
|
|
224
|
|
225 // rdar ://8218839
|
|
226 const char * (^func)(void) = ^{ return __func__; };
|
|
227 const char * (^function)(void) = ^{ return __FUNCTION__; };
|
|
228 const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };
|