1 // RUN: %clang_cc1 -no-opaque-pointers %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
2 
3 // CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
4 // CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 36, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* null }, align 8
5 
6 namespace test0 {
7   // CHECK-LABEL: define{{.*}} void @_ZN5test04testEi(
8   // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
9   // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}(
test(int x)10   void test(int x) {
11     ^{ ^{ (void) x; }; };
12   }
13 }
14 
15 extern void (^out)();
16 
17 namespace test1 {
18   // Capturing const objects doesn't require a local block.
19   // CHECK-LABEL: define{{.*}} void @_ZN5test15test1Ev()
20   // CHECK:   store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
test1()21   void test1() {
22     const int NumHorsemen = 4;
23     out = ^{ (void) NumHorsemen; };
24   }
25 
26   // That applies to structs too...
27   // CHECK-LABEL: define{{.*}} void @_ZN5test15test2Ev()
28   // CHECK:   store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
29   struct loc { double x, y; };
test2()30   void test2() {
31     const loc target = { 5, 6 };
32     out = ^{ (void) target; };
33   }
34 
35   // ...unless they have mutable fields...
36   // CHECK-LABEL: define{{.*}} void @_ZN5test15test3Ev()
37   // CHECK:   [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
38   // CHECK:   [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
39   // CHECK:   store void ()* [[T0]], void ()** @out
40   struct mut { mutable int x; };
test3()41   void test3() {
42     const mut obj = { 5 };
43     out = ^{ (void) obj; };
44   }
45 
46   // ...or non-trivial destructors...
47   // CHECK-LABEL: define{{.*}} void @_ZN5test15test4Ev()
48   // CHECK:   [[OBJ:%.*]] = alloca
49   // CHECK:   [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
50   // CHECK:   [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
51   // CHECK:   store void ()* [[T0]], void ()** @out
52   struct scope { int x; ~scope(); };
test4()53   void test4() {
54     const scope obj = { 5 };
55     out = ^{ (void) obj; };
56   }
57 
58   // ...or non-trivial copy constructors, but it's not clear how to do
59   // that and still have a constant initializer in '03.
60 }
61 
62 namespace test2 {
63   struct A {
64     A();
65     A(const A &);
66     ~A();
67   };
68 
69   struct B {
70     B();
71     B(const B &);
72     ~B();
73   };
74 
75   // CHECK-LABEL: define{{.*}} void @_ZN5test24testEv()
test()76   void test() {
77     __block A a;
78     __block B b;
79     ^{ (void)a; (void)b; };
80   }
81 
82   // CHECK-LABEL: define internal void @__Block_byref_object_copy
83   // CHECK: call void @_ZN5test21AC1ERKS0_(
84 
85   // CHECK-LABEL: define internal void @__Block_byref_object_dispose
86   // CHECK: call void @_ZN5test21AD1Ev(
87 
88   // CHECK-LABEL: define internal void @__Block_byref_object_copy
89   // CHECK: call void @_ZN5test21BC1ERKS0_(
90 
91   // CHECK-LABEL: define internal void @__Block_byref_object_dispose
92   // CHECK: call void @_ZN5test21BD1Ev(
93 }
94 
95 // rdar://problem/9334739
96 // Make sure we mark destructors for parameters captured in blocks.
97 namespace test3 {
98   struct A {
99     A(const A&);
100     ~A();
101   };
102 
103   struct B : A {
104   };
105 
test(B b)106   void test(B b) {
107     extern void consume(void(^)());
108     consume(^{ (void) b; });
109   }
110 }
111 
112 // rdar://problem/9971485
113 namespace test4 {
114   struct A {
115     A();
116     ~A();
117   };
118 
119   void foo(A a);
120 
test()121   void test() {
122     extern void consume(void(^)());
123     consume(^{ return foo(A()); });
124   }
125   // CHECK-LABEL: define{{.*}} void @_ZN5test44testEv()
126   // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
127   // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
128   // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
129   // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]* }>*
130   // CHECK:      call void @_ZN5test41AC1Ev([[A]]* {{[^,]*}} [[TMP]])
131   // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* noundef [[TMP]])
132   // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* {{[^,]*}} [[TMP]])
133   // CHECK-NEXT: ret void
134 }
135 
136 namespace test5 {
137   struct A {
138     unsigned afield;
139     A();
140     A(const A&);
141     ~A();
142     void foo() const;
143   };
144 
145   void doWithBlock(void(^)());
146 
test(bool cond)147   void test(bool cond) {
148     A x;
149     void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0);
150     doWithBlock(b);
151   }
152 
153   // CHECK-LABEL:    define{{.*}} void @_ZN5test54testEb(
154   // CHECK:      [[COND:%.*]] = alloca i8
155   // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4
156   // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8
157   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
158   // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
159   // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca [[A]]*, align 8
160   // CHECK-NEXT: [[T0:%.*]] = zext i1
161   // CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1
162   // CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* {{[^,]*}} [[X]])
163   // CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]], align 1
164   // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
165   // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]]
166   // CHECK-NEXT: br i1 [[T1]],
167 
168   // CHECK-NOT:  br
169   // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
170   // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* {{[^,]*}} [[CAPTURE]], [[A]]* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])
171   // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
172   // CHECK-NEXT: store [[A]]* [[CAPTURE]], [[A]]** [[COND_CLEANUP_SAVE]], align 8
173   // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
174   // CHECK-NEXT: br label
175   // CHECK:      br label
176   // CHECK:      phi
177   // CHECK-NEXT: store
178   // CHECK-NEXT: load
179   // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE(
180   // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]]
181   // CHECK-NEXT: br i1 [[T0]]
182   // CHECK:      [[T3:%.*]] = load [[A]]*, [[A]]** [[COND_CLEANUP_SAVE]], align 8
183   // CHECK-NEXT: call void @_ZN5test51AD1Ev([[A]]* {{[^,]*}} [[T3]])
184   // CHECK-NEXT: br label
185   // CHECK:      call void @_ZN5test51AD1Ev([[A]]* {{[^,]*}} [[X]])
186   // CHECK-NEXT: ret void
187 }
188 
189 namespace test6 {
190   struct A {
191     A();
192     ~A();
193   };
194 
195   void foo(const A &, void (^)());
196   void bar();
197 
test()198   void test() {
199     // Make sure that the temporary cleanup isn't somehow captured
200     // within the block.
201     foo(A(), ^{ bar(); });
202     bar();
203   }
204 
205   // CHECK-LABEL:    define{{.*}} void @_ZN5test64testEv()
206   // CHECK:      [[TEMP:%.*]] = alloca [[A:%.*]], align 1
207   // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* {{[^,]*}} [[TEMP]])
208   // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
209   // CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* {{[^,]*}} [[TEMP]])
210   // CHECK-NEXT: call void @_ZN5test63barEv()
211   // CHECK-NEXT: ret void
212 }
213 
214 namespace test7 {
f()215   int f() {
216     static int n;
217     int *const p = &n;
218     return ^{ return *p; }();
219   }
220 }
221 
222 namespace test8 {
223   // <rdar://problem/10832617>: failure to capture this after skipping rebuild
224   // of the 'this' pointer.
225   struct X {
226     int x;
227 
228     template<typename T>
footest8::X229     int foo() {
230       return ^ { return x; }();
231     }
232   };
233 
234   template int X::foo<int>();
235 }
236 
237 // rdar://13459289
238 namespace test9 {
239   struct B {
240     void *p;
241     B();
242     B(const B&);
243     ~B();
244   };
245 
246   void use_block(void (^)());
247   void use_block_2(void (^)(), const B &a);
248 
249   // Ensuring that creating a non-trivial capture copy expression
250   // doesn't end up stealing the block registration for the block we
251   // just parsed.  That block must have captures or else it won't
252   // force registration.  Must occur within a block for some reason.
test()253   void test() {
254     B x;
255     use_block(^{
256         int y;
257         use_block_2(^{ (void)y; }, x);
258     });
259   }
260 }
261 
262 namespace test10 {
263   // Check that 'v' is included in the copy helper function name to indicate
264   // the constructor taking a volatile parameter is called to copy the captured
265   // object.
266 
267   // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
268   // CHECK: call void @_ZN6test101BC1ERVKS0_(
269   // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
270   // CHECK: call void @_ZN6test101BD1Ev(
271 
272   struct B {
273     int a;
274     B();
275     B(const B &);
276     B(const volatile B &);
277     ~B();
278   };
279 
test()280   void test() {
281     volatile B x;
282     ^{ (void)x; };
283   }
284 }
285 
286 // Copy/dispose helper functions and block descriptors of blocks that capture
287 // objects that are non-external and non-trivial have internal linkage.
288 
289 // CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
290 // CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR22]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %{{.*}}, align 8
291 
292 // CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
293 // CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
294 
295 namespace {
296   struct B {
297     int a;
298     B();
299     B(const B &);
300     ~B();
301   };
302 
test()303   void test() {
304     B x;
305     ^{ (void)x; };
306   }
307 }
308 
callTest()309 void callTest() {
310   test();
311 }
312