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