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