1// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
2void donotwarn();
3
4int (^IFP) ();
5int (^II) (int);
6int 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
31int 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
44int^ x; // expected-error {{block pointer to non-function type is invalid}}
45int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
46
47void test3() {
48  char *^ y; // expected-error {{block pointer to non-function type is invalid}}
49}
50
51
52
53enum {NSBIRLazilyAllocated = 0};
54
55int 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
67void bar(void*);
68// rdar://6257721 - reference to static/global is byref by default.
69static int test5g;
70void test5() {
71  bar(^{ test5g = 1; });
72}
73
74// rdar://6405429 - __func__ in a block refers to the containing function name.
75const char*test6() {
76  return ^{
77    return __func__;
78  } ();
79}
80
81// radr://6732116 - block comparisons
82void (^test7a)();
83int test7(void (^p)()) {
84  return test7a == p;
85}
86
87
88void test8() {
89somelabel:
90  ^{ goto somelabel; }();   // expected-error {{use of undeclared label 'somelabel'}}
91}
92
93void test9() {
94  goto somelabel;       // expected-error {{use of undeclared label 'somelabel'}}
95  ^{ somelabel: ; }();
96}
97
98void test10(int i) {
99  switch (i) {
100  case 41: ;
101  ^{ case 42: ; }();     // expected-error {{'case' statement not in switch statement}}
102  }
103}
104
105void 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
115void (^test12f)(void);
116void test12() {
117  test12f = ^test12f;  // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}}
118}
119
120// rdar://6808730
121void *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
129void 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
140enum { LESS };
141
142void foo(long (^comp)()) { // expected-note{{passing argument to parameter 'comp' here}}
143}
144
145void (^test15f)(void);
146void 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
152void 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
160void f();
161
162void 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
186void test18() {
187  void (^const  blockA)(void) = ^{ };
188  blockA = ^{ }; // expected-error {{read-only variable is not assignable}}
189}
190
191// rdar://7072507
192int test19() {
193  goto L0;       // expected-error {{goto into protected scope}}
194
195  __block int x; // expected-note {{jump bypasses setup of __block variable}}
196L0:
197  x = 0;
198  ^(){ ++x; }();
199  return x;
200}
201
202// radr://7438948
203void 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
215void 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
226const char * (^func)(void) = ^{ return __func__; };
227const char * (^function)(void) = ^{ return __FUNCTION__; };
228const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };
229