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 Sambucint 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 Sambucvoid 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 Sambucint 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 Sambucvoid 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 Sambucconst 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 Sambucvoid test8() { 89f4a2713aSLionel Sambuc somelabel: 90f4a2713aSLionel Sambuc ^{ goto somelabel; }(); // expected-error {{use of undeclared label 'somelabel'}} 91f4a2713aSLionel Sambuc } 92f4a2713aSLionel Sambuc test9()93f4a2713aSLionel Sambucvoid test9() { 94f4a2713aSLionel Sambuc goto somelabel; // expected-error {{use of undeclared label 'somelabel'}} 95f4a2713aSLionel Sambuc ^{ somelabel: ; }(); 96f4a2713aSLionel Sambuc } 97f4a2713aSLionel Sambuc test10(int i)98f4a2713aSLionel Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucint 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 Sambucvoid 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 Sambucvoid 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