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