1 // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
3 // CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 36, ptr @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE, ptr @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE, ptr @{{.*}}, ptr null }, align 8
6 // CHECK-LABEL: define{{.*}} void @_ZN5test04testEi(
7 // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
8 // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}(
17 // Capturing const objects doesn't require a local block.
18 // CHECK-LABEL: define{{.*}} void @_ZN5test15test1Ev()
19 // CHECK: store ptr @__block_literal_global{{.*}}, ptr @out
21 const int NumHorsemen
= 4;
22 out
= ^{ (void) NumHorsemen
; };
25 // That applies to structs too...
26 // CHECK-LABEL: define{{.*}} void @_ZN5test15test2Ev()
27 // CHECK: store ptr @__block_literal_global{{.*}}, ptr @out
28 struct loc
{ double x
, y
; };
30 const loc target
= { 5, 6 };
31 out
= ^{ (void) target
; };
34 // ...unless they have mutable fields...
35 // CHECK-LABEL: define{{.*}} void @_ZN5test15test3Ev()
36 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
37 // CHECK: store ptr [[BLOCK]], ptr @out
38 struct mut
{ mutable int x
; };
40 const mut obj
= { 5 };
41 out
= ^{ (void) obj
; };
44 // ...or non-trivial destructors...
45 // CHECK-LABEL: define{{.*}} void @_ZN5test15test4Ev()
46 // CHECK: [[OBJ:%.*]] = alloca
47 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
48 // CHECK: store ptr [[BLOCK]], ptr @out
49 struct scope
{ int x
; ~scope(); };
51 const scope obj
= { 5 };
52 out
= ^{ (void) obj
; };
55 // ...or non-trivial copy constructors, but it's not clear how to do
56 // that and still have a constant initializer in '03.
72 // CHECK-LABEL: define{{.*}} void @_ZN5test24testEv()
76 ^{ (void)a
; (void)b
; };
79 // CHECK-LABEL: define internal void @__Block_byref_object_copy
80 // CHECK: call void @_ZN5test21AC1ERKS0_(
82 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
83 // CHECK: call void @_ZN5test21AD1Ev(
85 // CHECK-LABEL: define internal void @__Block_byref_object_copy
86 // CHECK: call void @_ZN5test21BC1ERKS0_(
88 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
89 // CHECK: call void @_ZN5test21BD1Ev(
92 // Make sure we mark destructors for parameters captured in blocks.
103 extern void consume(void(^)());
104 consume(^{ (void) b
; });
117 extern void consume(void(^)());
118 consume(^{ return foo(A()); });
120 // CHECK-LABEL: define{{.*}} void @_ZN5test44testEv()
121 // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
122 // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
123 // CHECK-NEXT: store ptr [[BLOCKDESC:%.*]], ptr {{.*}}, align 8
124 // CHECK: call void @_ZN5test41AC1Ev(ptr {{[^,]*}} [[TMP]])
125 // CHECK-NEXT: call void @_ZN5test43fooENS_1AE(ptr noundef [[TMP]])
126 // CHECK-NEXT: call void @_ZN5test41AD1Ev(ptr {{[^,]*}} [[TMP]])
127 // CHECK-NEXT: ret void
139 void doWithBlock(void(^)());
141 void test(bool cond
) {
143 void (^b
)() = (cond
? ^{ x
.foo(); } : (void(^)()) 0);
147 // CHECK-LABEL: define{{.*}} void @_ZN5test54testEb(
148 // CHECK: [[COND:%.*]] = alloca i8
149 // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4
150 // CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8
151 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
152 // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
153 // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca ptr, align 8
154 // CHECK-NEXT: [[T0:%.*]] = zext i1
155 // CHECK-NEXT: store i8 [[T0]], ptr [[COND]], align 1
156 // CHECK-NEXT: call void @_ZN5test51AC1Ev(ptr {{[^,]*}} [[X]])
157 // CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[COND]], align 1
158 // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
159 // CHECK-NEXT: store i1 false, ptr [[CLEANUP_ACTIVE]]
160 // CHECK-NEXT: br i1 [[T1]],
163 // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
164 // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_(ptr {{[^,]*}} [[CAPTURE]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])
165 // CHECK-NEXT: store i1 true, ptr [[CLEANUP_ACTIVE]]
166 // CHECK-NEXT: store ptr [[CAPTURE]], ptr [[COND_CLEANUP_SAVE]], align 8
167 // CHECK-NEXT: br label
172 // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE(
173 // CHECK-NEXT: [[T0:%.*]] = load i1, ptr [[CLEANUP_ACTIVE]]
174 // CHECK-NEXT: br i1 [[T0]]
175 // CHECK: [[T3:%.*]] = load ptr, ptr [[COND_CLEANUP_SAVE]], align 8
176 // CHECK-NEXT: call void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[T3]])
177 // CHECK-NEXT: br label
178 // CHECK: call void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[X]])
179 // CHECK-NEXT: ret void
188 void foo(const A
&, void (^)());
192 // Make sure that the temporary cleanup isn't somehow captured
194 foo(A(), ^{ bar(); });
198 // CHECK-LABEL: define{{.*}} void @_ZN5test64testEv()
199 // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1
200 // CHECK-NEXT: call void @_ZN5test61AC1Ev(ptr {{[^,]*}} [[TEMP]])
201 // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
202 // CHECK-NEXT: call void @_ZN5test61AD1Ev(ptr {{[^,]*}} [[TEMP]])
203 // CHECK-NEXT: call void @_ZN5test63barEv()
204 // CHECK-NEXT: ret void
211 return ^{ return *p
; }();
216 // failure to capture this after skipping rebuild of the 'this' pointer.
222 return ^ { return x
; }();
226 template int X::foo
<int>();
237 void use_block(void (^)());
238 void use_block_2(void (^)(), const B
&a
);
240 // Ensuring that creating a non-trivial capture copy expression
241 // doesn't end up stealing the block registration for the block we
242 // just parsed. That block must have captures or else it won't
243 // force registration. Must occur within a block for some reason.
248 use_block_2(^{ (void)y
; }, x
);
254 // Check that 'v' is included in the copy helper function name to indicate
255 // the constructor taking a volatile parameter is called to copy the captured
258 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
259 // CHECK: call void @_ZN6test101BC1ERVKS0_(
260 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
261 // CHECK: call void @_ZN6test101BD1Ev(
267 B(const volatile B
&);
277 // Copy/dispose helper functions and block descriptors of blocks that capture
278 // objects that are non-external and non-trivial have internal linkage.
280 // CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
281 // CHECK: store ptr @[[BLOCK_DESCRIPTOR22]], ptr %{{.*}}, align 8
283 // CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
284 // CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(