blob: 6c62376dc402f2cbc0eee94167beb6f27fc52394 [file] [log] [blame]
Daniel Dunbard7d5f022009-03-24 02:24:46 +00001// RUN: clang-cc -fsyntax-only -verify %s -fblocks
Steve Naroffdd972f22008-09-05 22:11:13 +00002void donotwarn();
3
4int (^IFP) ();
5int (^II) (int);
6int test1() {
Mike Stumpaab0f7a2009-04-01 01:17:39 +00007 int (^PFR) (int) = 0; // OK
8 PFR = II; // OK
Steve Naroffdd972f22008-09-05 22:11:13 +00009
Mike Stumpaab0f7a2009-04-01 01:17:39 +000010 if (PFR == II) // OK
11 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000012
Mike Stumpaab0f7a2009-04-01 01:17:39 +000013 if (PFR == IFP) // expected-error {{comparison of distinct block types}}
14 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000015
Mike Stumpaab0f7a2009-04-01 01:17:39 +000016 if (PFR == (int (^) (int))IFP) // OK
17 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000018
Mike Stumpaab0f7a2009-04-01 01:17:39 +000019 if (PFR == 0) // OK
20 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000021
Mike Stumpaab0f7a2009-04-01 01:17:39 +000022 if (PFR) // OK
23 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000024
Mike Stumpaab0f7a2009-04-01 01:17:39 +000025 if (!PFR) // OK
26 donotwarn();
Steve Naroffdd972f22008-09-05 22:11:13 +000027
Mike Stumpaab0f7a2009-04-01 01:17:39 +000028 return PFR != IFP; // expected-error {{comparison of distinct block types}}
Steve Naroffdd972f22008-09-05 22:11:13 +000029}
30
31int test2(double (^S)()) {
Mike Stumpaab0f7a2009-04-01 01:17:39 +000032 double (^I)(int) = (void*) S;
33 (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
Steve Naroffdd972f22008-09-05 22:11:13 +000034
Mike Stumpaab0f7a2009-04-01 01:17:39 +000035 void *pv = I;
Steve Naroffdd972f22008-09-05 22:11:13 +000036
Mike Stumpaab0f7a2009-04-01 01:17:39 +000037 pv = S;
Steve Naroffdd972f22008-09-05 22:11:13 +000038
Mike Stumpaab0f7a2009-04-01 01:17:39 +000039 I(1);
40
41 return (void*)I == (void *)S;
Steve Naroffdd972f22008-09-05 22:11:13 +000042}
43
44int^ x; // expected-error {{block pointer to non-function type is invalid}}
Mike Stumpbfa2ac02009-02-08 07:59:54 +000045int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
Steve Naroffdd972f22008-09-05 22:11:13 +000046
47int test3() {
Mike Stumpaab0f7a2009-04-01 01:17:39 +000048 char *^ y; // expected-error {{block pointer to non-function type is invalid}}
Steve Naroffdd972f22008-09-05 22:11:13 +000049}
50
Chris Lattnerf7037b12008-09-28 05:30:26 +000051
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}
Chris Lattner639e2d32008-10-20 05:16:36 +000065
66
67// rdar://6257721 - reference to static/global is byref by default.
68static int test5g;
69void test5() {
70 bar(^{ test5g = 1; });
71}
72
Chris Lattner371f2582008-12-04 23:50:19 +000073// rdar://6405429 - __func__ in a block refers to the containing function name.
74const char*test6() {
Mike Stumpaab0f7a2009-04-01 01:17:39 +000075 return ^{
76 return __func__;
77 } ();
Chris Lattner371f2582008-12-04 23:50:19 +000078}
79
Mike Stumpaab0f7a2009-04-01 01:17:39 +000080// radr://6732116 - block comparisons
Chris Lattner5718a352009-04-18 19:32:54 +000081void (^test7a)();
82int test7(void (^p)()) {
83 return test7a == p;
Mike Stumpaab0f7a2009-04-01 01:17:39 +000084}
Chris Lattner5718a352009-04-18 19:32:54 +000085
86
87void test8() {
88somelabel:
89 // FIXME: This should say "jump out of block not legal" when gotos are allowed.
90 ^{ goto somelabel; }(); // expected-error {{goto not allowed in block literal}}
91}
92
93void test9() {
94 goto somelabel; // expected-error {{use of undeclared label 'somelabel'}}
95 ^{ somelabel: ; }();
96}
97
Chris Lattnerbcfce662009-04-18 20:10:59 +000098void 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
Chris Lattner5c59e2b2009-04-21 22:38:46 +0000115void (^test12f)(void);
116void test12() {
Mike Stump914d3db2009-04-21 23:03:34 +0000117 test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}}
Chris Lattner5c59e2b2009-04-21 22:38:46 +0000118}
119
Chris Lattner17f3a6d2009-04-21 22:26:47 +0000120// 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}
Mike Stump25efa102009-04-21 22:51:42 +0000139
Mike Stump914d3db2009-04-21 23:03:34 +0000140enum { LESS };
141
142void foo(long (^comp)()) {
143}
144
145void (^test15f)(void);
146void test15() {
147 foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)()'}}
Mike Stump25efa102009-04-21 22:51:42 +0000148}
Mike Stumpea000bf2009-04-30 00:19:40 +0000149
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}}
Mike Stumpc975bb02009-05-01 23:41:47 +0000153 int size = 5;
Mike Stumpea000bf2009-04-30 00:19:40 +0000154 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}}
Mike Stumpc975bb02009-05-01 23:41:47 +0000156 __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}}
Mike Stumpea000bf2009-04-30 00:19:40 +0000158}
Mike Stumpdd3e1662009-05-07 03:14:14 +0000159
160void test17() {
161 void (^bp)(int);
162 void (*rp)(int);
163 void (^bp1)();
164 void *vp = bp;
165
166 f(1 ? bp : vp);
167 f(1 ? vp : bp);
168 f(1 ? bp : bp1); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (^)()')}}
169 (void)(bp > rp); // expected-error {{invalid operands}}
170 (void)(bp > 0); // expected-error {{invalid operands}}
171 (void)(bp > bp); // expected-error {{invalid operands}}
172 (void)(bp > vp); // expected-error {{invalid operands}}
173 f(1 ? bp : rp); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (*)(int)')}}
Mike Stumpaf199f32009-05-07 18:43:07 +0000174 (void)(bp == 1); // expected-error {{invalid operands to binary expression}}
175 (void)(bp == 0);
176 (void)(1 == bp); // expected-error {{invalid operands to binary expression}}
177 (void)(0 == bp);
178 (void)(bp < 1); // expected-error {{invalid operands to binary expression}}
179 (void)(bp < 0); // expected-error {{invalid operands to binary expression}}
180 (void)(1 < bp); // expected-error {{invalid operands to binary expression}}
181 (void)(0 < bp); // expected-error {{invalid operands to binary expression}}
Mike Stumpdd3e1662009-05-07 03:14:14 +0000182}