1 // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s 2 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 4 5 namespace test0 { 6 // CHECK-LABEL: define{{.*}} void @_ZN5test04testEi( 7 // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}( 8 // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}( 9 void test(int x) { 10 ^{ ^{ (void) x; }; }; 11 } 12 } 13 14 extern void (^out)(); 15 16 namespace test1 { 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 20 void test1() { 21 const int NumHorsemen = 4; 22 out = ^{ (void) NumHorsemen; }; 23 } 24 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; }; 29 void test2() { 30 const loc target = { 5, 6 }; 31 out = ^{ (void) target; }; 32 } 33 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; }; 39 void test3() { 40 const mut obj = { 5 }; 41 out = ^{ (void) obj; }; 42 } 43 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(); }; 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() 73 void test() { 74 __block A a; 75 __block B b; 76 ^{ (void)a; (void)b; }; 77 } 78 79 // CHECK-LABEL: define internal void @__Block_byref_object_copy 80 // CHECK: call void @_ZN5test21AC1ERKS0_( 81 82 // CHECK-LABEL: define internal void @__Block_byref_object_dispose 83 // CHECK: call void @_ZN5test21AD1Ev( 84 85 // CHECK-LABEL: define internal void @__Block_byref_object_copy 86 // CHECK: call void @_ZN5test21BC1ERKS0_( 87 88 // CHECK-LABEL: define internal void @__Block_byref_object_dispose 89 // CHECK: call void @_ZN5test21BD1Ev( 90 } 91 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 102 void test(B b) { 103 extern void consume(void(^)()); 104 consume(^{ (void) b; }); 105 } 106 } 107 108 namespace test4 { 109 struct A { 110 A(); 111 ~A(); 112 }; 113 114 void foo(A a); 115 116 void test() { 117 extern void consume(void(^)()); 118 consume(^{ return foo(A()); }); 119 } 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 128 } 129 130 namespace test5 { 131 struct A { 132 unsigned afield; 133 A(); 134 A(const A&); 135 ~A(); 136 void foo() const; 137 }; 138 139 void doWithBlock(void(^)()); 140 141 void test(bool cond) { 142 A x; 143 void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0); 144 doWithBlock(b); 145 } 146 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: [[COND_CLEANUP_SAVE:%.*]] = alloca ptr, align 8 153 // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1 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]], 161 162 // CHECK-NOT: br 163 // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds nuw [[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 ptr [[CAPTURE]], ptr [[COND_CLEANUP_SAVE]], align 8 166 // CHECK-NEXT: store i1 true, ptr [[CLEANUP_ACTIVE]] 167 // CHECK-NEXT: br label 168 // CHECK: br label 169 // CHECK: phi 170 // CHECK-NEXT: store 171 // CHECK-NEXT: load 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 180 } 181 182 namespace test6 { 183 struct A { 184 A(); 185 ~A(); 186 }; 187 188 void foo(const A &, void (^)()); 189 void bar(); 190 191 void test() { 192 // Make sure that the temporary cleanup isn't somehow captured 193 // within the block. 194 foo(A(), ^{ bar(); }); 195 bar(); 196 } 197 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 205 } 206 207 namespace test7 { 208 int f() { 209 static int n; 210 int *const p = &n; 211 return ^{ return *p; }(); 212 } 213 } 214 215 namespace test8 { 216 // failure to capture this after skipping rebuild of the 'this' pointer. 217 struct X { 218 int x; 219 220 template<typename T> 221 int foo() { 222 return ^ { return x; }(); 223 } 224 }; 225 226 template int X::foo<int>(); 227 } 228 229 namespace test9 { 230 struct B { 231 void *p; 232 B(); 233 B(const B&); 234 ~B(); 235 }; 236 237 void use_block(void (^)()); 238 void use_block_2(void (^)(), const B &a); 239 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. 244 void test() { 245 B x; 246 use_block(^{ 247 int y; 248 use_block_2(^{ (void)y; }, x); 249 }); 250 } 251 } 252 253 namespace test10 { 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 256 // object. 257 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( 262 263 struct B { 264 int a; 265 B(); 266 B(const B &); 267 B(const volatile B &); 268 ~B(); 269 }; 270 271 void test() { 272 volatile B x; 273 ^{ (void)x; }; 274 } 275 } 276 277 // Copy/dispose helper functions and block descriptors of blocks that capture 278 // objects that are non-external and non-trivial have internal linkage. 279 280 // CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv( 281 // CHECK: store ptr @[[BLOCK_DESCRIPTOR22]], ptr %{{.*}}, align 8 282 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( 285 286 namespace { 287 struct B { 288 int a; 289 B(); 290 B(const B &); 291 ~B(); 292 }; 293 294 void test() { 295 B x; 296 ^{ (void)x; }; 297 } 298 } 299 300 void callTest() { 301 test(); 302 } 303