Daniel Dunbar | d7d5f02 | 2009-03-24 02:24:46 +0000 | [diff] [blame] | 1 | // RUN: clang-cc -fsyntax-only -verify %s -fblocks |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 2 | void donotwarn(); |
| 3 | |
| 4 | int (^IFP) (); |
| 5 | int (^II) (int); |
| 6 | int test1() { |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 7 | int (^PFR) (int) = 0; // OK |
| 8 | PFR = II; // OK |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 9 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 10 | if (PFR == II) // OK |
| 11 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 12 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 13 | if (PFR == IFP) // expected-error {{comparison of distinct block types}} |
| 14 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 15 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 16 | if (PFR == (int (^) (int))IFP) // OK |
| 17 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 18 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 19 | if (PFR == 0) // OK |
| 20 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 21 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 22 | if (PFR) // OK |
| 23 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 24 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 25 | if (!PFR) // OK |
| 26 | donotwarn(); |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 27 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 28 | return PFR != IFP; // expected-error {{comparison of distinct block types}} |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 29 | } |
| 30 | |
| 31 | int test2(double (^S)()) { |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 32 | double (^I)(int) = (void*) S; |
| 33 | (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 34 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 35 | void *pv = I; |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 36 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 37 | pv = S; |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 38 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 39 | I(1); |
| 40 | |
| 41 | return (void*)I == (void *)S; |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | int^ x; // expected-error {{block pointer to non-function type is invalid}} |
Mike Stump | bfa2ac0 | 2009-02-08 07:59:54 +0000 | [diff] [blame] | 45 | int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}} |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 46 | |
| 47 | int test3() { |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 48 | char *^ y; // expected-error {{block pointer to non-function type is invalid}} |
Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 49 | } |
| 50 | |
Chris Lattner | f7037b1 | 2008-09-28 05:30:26 +0000 | [diff] [blame] | 51 | |
| 52 | |
| 53 | enum {NSBIRLazilyAllocated = 0}; |
| 54 | |
| 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 | } |
Chris Lattner | 639e2d3 | 2008-10-20 05:16:36 +0000 | [diff] [blame] | 65 | |
| 66 | |
| 67 | // rdar://6257721 - reference to static/global is byref by default. |
| 68 | static int test5g; |
| 69 | void test5() { |
| 70 | bar(^{ test5g = 1; }); |
| 71 | } |
| 72 | |
Chris Lattner | 371f258 | 2008-12-04 23:50:19 +0000 | [diff] [blame] | 73 | // rdar://6405429 - __func__ in a block refers to the containing function name. |
| 74 | const char*test6() { |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 75 | return ^{ |
| 76 | return __func__; |
| 77 | } (); |
Chris Lattner | 371f258 | 2008-12-04 23:50:19 +0000 | [diff] [blame] | 78 | } |
| 79 | |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 80 | // radr://6732116 - block comparisons |
Chris Lattner | 5718a35 | 2009-04-18 19:32:54 +0000 | [diff] [blame] | 81 | void (^test7a)(); |
| 82 | int test7(void (^p)()) { |
| 83 | return test7a == p; |
Mike Stump | aab0f7a | 2009-04-01 01:17:39 +0000 | [diff] [blame] | 84 | } |
Chris Lattner | 5718a35 | 2009-04-18 19:32:54 +0000 | [diff] [blame] | 85 | |
| 86 | |
| 87 | void test8() { |
| 88 | somelabel: |
| 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 | |
| 93 | void test9() { |
| 94 | goto somelabel; // expected-error {{use of undeclared label 'somelabel'}} |
| 95 | ^{ somelabel: ; }(); |
| 96 | } |
| 97 | |
Chris Lattner | bcfce66 | 2009-04-18 20:10:59 +0000 | [diff] [blame] | 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 | |
| 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 | |
Chris Lattner | 5c59e2b | 2009-04-21 22:38:46 +0000 | [diff] [blame] | 115 | void (^test12f)(void); |
| 116 | void test12() { |
Mike Stump | 914d3db | 2009-04-21 23:03:34 +0000 | [diff] [blame] | 117 | test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}} |
Chris Lattner | 5c59e2b | 2009-04-21 22:38:46 +0000 | [diff] [blame] | 118 | } |
| 119 | |
Chris Lattner | 17f3a6d | 2009-04-21 22:26:47 +0000 | [diff] [blame] | 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 | |
| 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 | } |
Mike Stump | 25efa10 | 2009-04-21 22:51:42 +0000 | [diff] [blame] | 139 | |
Mike Stump | 914d3db | 2009-04-21 23:03:34 +0000 | [diff] [blame] | 140 | enum { LESS }; |
| 141 | |
| 142 | void foo(long (^comp)()) { |
| 143 | } |
| 144 | |
| 145 | void (^test15f)(void); |
| 146 | void test15() { |
| 147 | foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)()'}} |
Mike Stump | 25efa10 | 2009-04-21 22:51:42 +0000 | [diff] [blame] | 148 | } |
Mike Stump | ea000bf | 2009-04-30 00:19:40 +0000 | [diff] [blame] | 149 | |
| 150 | __block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}} |
| 151 | |
| 152 | void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}} |
Mike Stump | c975bb0 | 2009-05-01 23:41:47 +0000 | [diff] [blame] | 153 | int size = 5; |
Mike Stump | ea000bf | 2009-04-30 00:19:40 +0000 | [diff] [blame] | 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}} |
Mike Stump | c975bb0 | 2009-05-01 23:41:47 +0000 | [diff] [blame] | 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}} |
Mike Stump | ea000bf | 2009-04-30 00:19:40 +0000 | [diff] [blame] | 158 | } |
Mike Stump | dd3e166 | 2009-05-07 03:14:14 +0000 | [diff] [blame^] | 159 | |
| 160 | void 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)')}} |
| 174 | } |