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