// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks void donotwarn(); int (^IFP) (); int (^II) (int); int test1() { int (^PFR) (int) = 0; // OK PFR = II; // OK if (PFR == II) // OK donotwarn(); if (PFR == IFP) // OK donotwarn(); if (PFR == (int (^) (int))IFP) // OK donotwarn(); if (PFR == 0) // OK donotwarn(); if (PFR) // OK donotwarn(); if (!PFR) // OK donotwarn(); return PFR != IFP; // OK } int test2(double (^S)()) { double (^I)(int) = (void*) S; (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} void *pv = I; pv = S; I(1); return (void*)I == (void *)S; } int^ x; // expected-error {{block pointer to non-function type is invalid}} int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}} void test3() { char *^ y; // expected-error {{block pointer to non-function type is invalid}} } enum {NSBIRLazilyAllocated = 0}; int test4(int argc) { // rdar://6251437 ^{ switch (argc) { case NSBIRLazilyAllocated: // is an integer constant expression. default: break; } }(); return 0; } void bar(void*); // rdar://6257721 - reference to static/global is byref by default. static int test5g; void test5() { bar(^{ test5g = 1; }); } // rdar://6405429 - __func__ in a block refers to the containing function name. const char*test6() { return ^{ return __func__; } (); } // radr://6732116 - block comparisons void (^test7a)(); int test7(void (^p)()) { return test7a == p; } void test8() { somelabel: ^{ goto somelabel; }(); // expected-error {{use of undeclared label 'somelabel'}} } void test9() { goto somelabel; // expected-error {{use of undeclared label 'somelabel'}} ^{ somelabel: ; }(); } void test10(int i) { switch (i) { case 41: ; ^{ case 42: ; }(); // expected-error {{'case' statement not in switch statement}} } } void test11(int i) { switch (i) { case 41: ; ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}} } for (; i < 100; ++i) ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}} } void (^test12f)(void); void test12() { test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}} } // rdar://6808730 void *test13 = ^{ int X = 32; void *P = ^{ return X+4; // References outer block's "X", so outer block is constant. }; }; void test14() { int X = 32; static void *P = ^{ // expected-error {{initializer element is not a compile-time constant}} void *Q = ^{ // References test14's "X": outer block is non-constant. return X+4; }; }; } enum { LESS }; void foo(long (^comp)()) { // expected-note{{passing argument to parameter 'comp' here}} } void (^test15f)(void); void test15() { foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)' to parameter of type 'long (^)()'}} } __block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}} void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}} int size = 5; extern __block double extern_var; // expected-error {{__block attribute not allowed, only allowed on local variables}} static __block char * pch; // expected-error {{__block attribute not allowed, only allowed on local variables}} __block int a[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}} __block int (*ap)[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}} } void f(); void test17() { void (^bp)(int); void (*rp)(int); void (^bp1)(); void *vp = bp; f(1 ? bp : vp); f(1 ? vp : bp); f(1 ? bp : bp1); (void)(bp > rp); // expected-error {{invalid operands}} (void)(bp > 0); // expected-error {{invalid operands}} (void)(bp > bp); // expected-error {{invalid operands}} (void)(bp > vp); // expected-error {{invalid operands}} f(1 ? bp : rp); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (*)(int)')}} (void)(bp == 1); // expected-error {{invalid operands to binary expression}} (void)(bp == 0); (void)(1 == bp); // expected-error {{invalid operands to binary expression}} (void)(0 == bp); (void)(bp < 1); // expected-error {{invalid operands to binary expression}} (void)(bp < 0); // expected-error {{invalid operands to binary expression}} (void)(1 < bp); // expected-error {{invalid operands to binary expression}} (void)(0 < bp); // expected-error {{invalid operands to binary expression}} } void test18() { void (^const blockA)(void) = ^{ }; // expected-note {{variable 'blockA' declared const here}} blockA = ^{ }; // expected-error {{cannot assign to variable 'blockA' with const-qualified type 'void (^const)(void)}} } // rdar://7072507 int test19() { goto L0; // expected-error {{cannot jump}} __block int x; // expected-note {{jump bypasses setup of __block variable}} L0: x = 0; ^(){ ++x; }(); return x; } // radr://7438948 void test20() { int n = 7; int vla[n]; // expected-note {{declared here}} int (*vm)[n] = 0; // expected-note {{declared here}} vla[1] = 4341; ^{ (void)vla[1]; // expected-error {{cannot refer to declaration with a variably modified type inside block}} (void)(vm+1); // expected-error {{cannot refer to declaration with a variably modified type inside block}} }(); } // radr://7438948 void test21() { int a[7]; // expected-note {{declared here}} __block int b[10]; // expected-note {{declared here}} a[1] = 1; ^{ (void)a[1]; // expected-error {{cannot refer to declaration with an array type inside block}} (void)b[1]; // expected-error {{cannot refer to declaration with an array type inside block}} }(); } // rdar ://8218839 const char * (^func)(void) = ^{ return __func__; }; const char * (^function)(void) = ^{ return __FUNCTION__; }; const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };