[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaObjCXX / blocks.mm
blob0ae91ab985ac14eb84d80954a70ff82382fc8f70
1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s
2 @protocol NSObject;
4 void bar(id(^)(void));
5 void foo(id <NSObject>(^objectCreationBlock)(void)) {
6     return bar(objectCreationBlock); // OK
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 (*)()'}}
14 void bar3(id(*)()); // expected-note{{candidate function}}
15 void foo3(id (*objectCreationBlock)(int)) {
16     return bar3(objectCreationBlock); // expected-error{{no matching}}
19 void bar4(id(^)()); // expected-note{{candidate function}}
20 void foo4(id (^objectCreationBlock)(int)) {
21     return bar4(objectCreationBlock); // expected-error{{no matching}}
24 void foo5(id (^x)(int)) {
25   if (x) { }
28 @interface Foo {
29     @private
30     void (^_block)(void);
32 - (void)bar;
33 @end
35 namespace N {
36   class X { };      
37   void foo(X);
40 @implementation Foo
41 - (void)bar {
42     _block();
43     foo(N::X()); // okay
45 @end
47 typedef signed char BOOL;
48 void 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;
53 // Require that the types of block parameters are complete.
54 namespace N1 {
55   template<class _T> class ptr; // expected-note{{template is declared here}}
57   template<class _T>
58     class foo {
59   public:
60     void bar(void (^)(ptr<_T>));
61   };
63   class X;
65   void test2();
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   }
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.
78 namespace 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   };
87   typedef void (^BlockFnTy)();
88   void func(BlockFnTy);
90   void test1() {
91     __block A<1> x; // expected-note {{requested here}}
92     func(^{ x.m(); });
93   }
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>();
102 // Handle value-dependent block declaration references.
103 namespace N3 {
104   template<int N> struct X { };
106   template<int N>
107   void f() {
108     X<N> xN = ^() { return X<N>(); }();
109   }
112 @interface A
113 @end
115 @interface B : A
116 @end
118 void f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no known conversion from 'int (^)(B *)' to 'int (^)(A *)' for 1st argument}}
120 void g() {
121   f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}}
124 namespace 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     };
134     (void)^(T u) {
135       if (t == u)
136         return;
137       else
138         return t + u;
139     };
140   }
142   struct X { };
143   void operator+(X, X);
144   bool operator==(X, X);
145   bool operator!=(X, X);
147   template void f<X>(X);
150 namespace GenericLambdaCapture {
151 int test(int outerp) {
152   auto lambda =[&](auto p) {
153     return ^{
154       return p + outerp;
155     }();
156   };
157   return lambda(1);
161 namespace MoveBlockVariable {
162 struct B0 {
165 struct B1 { // expected-note 2 {{candidate constructor (the implicit}}
166   B1(B0&&); // expected-note {{candidate constructor not viable}}
169 B1 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'}}