1 // RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
2 void donotwarn();
3 
4 int (^IFP) ();
5 int (^II) (int);
test1()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 
test3()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 
test4(int argc)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;
test5()70 void test5() {
71   bar(^{ test5g = 1; });
72 }
73 
74 // rdar://6405429 - __func__ in a block refers to the containing function name.
test6()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 
test8()88 void test8() {
89 somelabel:
90   ^{ goto somelabel; }();   // expected-error {{use of undeclared label 'somelabel'}}
91 }
92 
test9()93 void test9() {
94   goto somelabel;       // expected-error {{use of undeclared label 'somelabel'}}
95   ^{ somelabel: ; }();
96 }
97 
test10(int i)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 
test11(int i)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);
test12()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 
test14()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);
test15()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 
test16(__block int i)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 
test17()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 
test18()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
test19()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
test20()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
test21()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__; };
229