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