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