1*f4a2713aSLionel Sambuc// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s 2*f4a2713aSLionel Sambuc@protocol NSObject; 3*f4a2713aSLionel Sambuc 4*f4a2713aSLionel Sambucvoid bar(id(^)(void)); 5*f4a2713aSLionel Sambucvoid foo(id <NSObject>(^objectCreationBlock)(void)) { 6*f4a2713aSLionel Sambuc return bar(objectCreationBlock); // OK 7*f4a2713aSLionel Sambuc} 8*f4a2713aSLionel Sambuc 9*f4a2713aSLionel Sambucvoid bar2(id(*)(void)); 10*f4a2713aSLionel Sambucvoid foo2(id <NSObject>(*objectCreationBlock)(void)) { 11*f4a2713aSLionel Sambuc return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id<NSObject> (*)()' to parameter of type 'id (*)()'}} 12*f4a2713aSLionel Sambuc} 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambucvoid bar3(id(*)()); // expected-note{{candidate function}} 15*f4a2713aSLionel Sambucvoid foo3(id (*objectCreationBlock)(int)) { 16*f4a2713aSLionel Sambuc return bar3(objectCreationBlock); // expected-error{{no matching}} 17*f4a2713aSLionel Sambuc} 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambucvoid bar4(id(^)()); // expected-note{{candidate function}} 20*f4a2713aSLionel Sambucvoid foo4(id (^objectCreationBlock)(int)) { 21*f4a2713aSLionel Sambuc return bar4(objectCreationBlock); // expected-error{{no matching}} 22*f4a2713aSLionel Sambuc} 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambucvoid foo5(id (^x)(int)) { 25*f4a2713aSLionel Sambuc if (x) { } 26*f4a2713aSLionel Sambuc} 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc// <rdar://problem/6590445> 29*f4a2713aSLionel Sambuc@interface Foo { 30*f4a2713aSLionel Sambuc @private 31*f4a2713aSLionel Sambuc void (^_block)(void); 32*f4a2713aSLionel Sambuc} 33*f4a2713aSLionel Sambuc- (void)bar; 34*f4a2713aSLionel Sambuc@end 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambucnamespace N { 37*f4a2713aSLionel Sambuc class X { }; 38*f4a2713aSLionel Sambuc void foo(X); 39*f4a2713aSLionel Sambuc} 40*f4a2713aSLionel Sambuc 41*f4a2713aSLionel Sambuc@implementation Foo 42*f4a2713aSLionel Sambuc- (void)bar { 43*f4a2713aSLionel Sambuc _block(); 44*f4a2713aSLionel Sambuc foo(N::X()); // okay 45*f4a2713aSLionel Sambuc} 46*f4a2713aSLionel Sambuc@end 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuctypedef signed char BOOL; 49*f4a2713aSLionel Sambucvoid foo6(void *block) { 50*f4a2713aSLionel Sambuc void (^vb)(id obj, int idx, BOOL *stop) = (void (^)(id, int, BOOL *))block; 51*f4a2713aSLionel Sambuc BOOL (^bb)(id obj, int idx, BOOL *stop) = (BOOL (^)(id, int, BOOL *))block; 52*f4a2713aSLionel Sambuc} 53*f4a2713aSLionel Sambuc 54*f4a2713aSLionel Sambuc// <rdar://problem/8600419>: Require that the types of block 55*f4a2713aSLionel Sambuc// parameters are complete. 56*f4a2713aSLionel Sambucnamespace N1 { 57*f4a2713aSLionel Sambuc template<class _T> class ptr; // expected-note{{template is declared here}} 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc template<class _T> 60*f4a2713aSLionel Sambuc class foo { 61*f4a2713aSLionel Sambuc public: 62*f4a2713aSLionel Sambuc void bar(void (^)(ptr<_T>)); 63*f4a2713aSLionel Sambuc }; 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc class X; 66*f4a2713aSLionel Sambuc 67*f4a2713aSLionel Sambuc void test2(); 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambuc void test() 70*f4a2713aSLionel Sambuc { 71*f4a2713aSLionel Sambuc foo<X> f; 72*f4a2713aSLionel Sambuc f.bar(^(ptr<X> _f) { // expected-error{{implicit instantiation of undefined template 'N1::ptr<N1::X>'}} 73*f4a2713aSLionel Sambuc test2(); 74*f4a2713aSLionel Sambuc }); 75*f4a2713aSLionel Sambuc } 76*f4a2713aSLionel Sambuc} 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc// Make sure we successfully instantiate the copy constructor of a 79*f4a2713aSLionel Sambuc// __block variable's type. 80*f4a2713aSLionel Sambucnamespace N2 { 81*f4a2713aSLionel Sambuc template <int n> struct A { 82*f4a2713aSLionel Sambuc A() {} 83*f4a2713aSLionel Sambuc A(const A &other) { 84*f4a2713aSLionel Sambuc int invalid[-n]; // expected-error 2 {{array with a negative size}} 85*f4a2713aSLionel Sambuc } 86*f4a2713aSLionel Sambuc }; 87*f4a2713aSLionel Sambuc 88*f4a2713aSLionel Sambuc void test1() { 89*f4a2713aSLionel Sambuc __block A<1> x; // expected-note {{requested here}} 90*f4a2713aSLionel Sambuc } 91*f4a2713aSLionel Sambuc 92*f4a2713aSLionel Sambuc template <int n> void test2() { 93*f4a2713aSLionel Sambuc __block A<n> x; // expected-note {{requested here}} 94*f4a2713aSLionel Sambuc } 95*f4a2713aSLionel Sambuc template void test2<2>(); 96*f4a2713aSLionel Sambuc} 97*f4a2713aSLionel Sambuc 98*f4a2713aSLionel Sambuc// Handle value-dependent block declaration references. 99*f4a2713aSLionel Sambucnamespace N3 { 100*f4a2713aSLionel Sambuc template<int N> struct X { }; 101*f4a2713aSLionel Sambuc 102*f4a2713aSLionel Sambuc template<int N> 103*f4a2713aSLionel Sambuc void f() { 104*f4a2713aSLionel Sambuc X<N> xN = ^() { return X<N>(); }(); 105*f4a2713aSLionel Sambuc } 106*f4a2713aSLionel Sambuc} 107*f4a2713aSLionel Sambuc 108*f4a2713aSLionel Sambuc// rdar://8979379 109*f4a2713aSLionel Sambuc 110*f4a2713aSLionel Sambuc@interface A 111*f4a2713aSLionel Sambuc@end 112*f4a2713aSLionel Sambuc 113*f4a2713aSLionel Sambuc@interface B : A 114*f4a2713aSLionel Sambuc@end 115*f4a2713aSLionel Sambuc 116*f4a2713aSLionel Sambucvoid f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no known conversion from 'int (^)(B *)' to 'int (^)(A *)' for 1st argument}} 117*f4a2713aSLionel Sambuc 118*f4a2713aSLionel Sambucvoid g() { 119*f4a2713aSLionel Sambuc f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}} 120*f4a2713aSLionel Sambuc} 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambucnamespace DependentReturn { 123*f4a2713aSLionel Sambuc template<typename T> 124*f4a2713aSLionel Sambuc void f(T t) { 125*f4a2713aSLionel Sambuc (void)^(T u) { 126*f4a2713aSLionel Sambuc if (t != u) 127*f4a2713aSLionel Sambuc return t + u; 128*f4a2713aSLionel Sambuc else 129*f4a2713aSLionel Sambuc return; 130*f4a2713aSLionel Sambuc }; 131*f4a2713aSLionel Sambuc 132*f4a2713aSLionel Sambuc (void)^(T u) { 133*f4a2713aSLionel Sambuc if (t == u) 134*f4a2713aSLionel Sambuc return; 135*f4a2713aSLionel Sambuc else 136*f4a2713aSLionel Sambuc return t + u; 137*f4a2713aSLionel Sambuc }; 138*f4a2713aSLionel Sambuc } 139*f4a2713aSLionel Sambuc 140*f4a2713aSLionel Sambuc struct X { }; 141*f4a2713aSLionel Sambuc void operator+(X, X); 142*f4a2713aSLionel Sambuc bool operator==(X, X); 143*f4a2713aSLionel Sambuc bool operator!=(X, X); 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc template void f<X>(X); 146*f4a2713aSLionel Sambuc} 147