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