1 // RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s 2 3 // CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4 4 // CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0 5 // CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 1 6 // CHECK: @_ZGVZN5test84testEvE1x = internal global i32 0 7 8 typedef typeof(sizeof(int)) size_t; 9 10 class foo { 11 public: 12 foo(); 13 virtual ~foo(); 14 }; 15 16 class bar : public foo { 17 public: 18 bar(); 19 }; 20 21 // The global dtor needs the right calling conv with -fno-use-cxa-atexit 22 // rdar://7817590 23 bar baz; 24 25 // PR9593 26 // Make sure atexit(3) is used for global dtors. 27 28 // CHECK: call [[BAR:%.*]]* @_ZN3barC1Ev( 29 // CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz) 30 31 // CHECK-NOT: @_GLOBAL__D_a() 32 // CHECK-LABEL: define internal void @__dtor_baz() 33 // CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz) 34 35 // Destructors and constructors must return this. 36 namespace test1 { 37 void foo(); 38 39 struct A { 40 A(int i) { foo(); } 41 ~A() { foo(); } 42 void bar() { foo(); } 43 }; 44 45 // CHECK-LABEL: define void @_ZN5test14testEv() 46 void test() { 47 // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1 48 // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10) 49 // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]]) 50 // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]]) 51 // CHECK: ret void 52 A a = 10; 53 a.bar(); 54 } 55 56 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* returned %this, i32 %i) unnamed_addr 57 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 58 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] 59 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] 60 // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AC2Ei( 61 // CHECK: ret [[A]]* [[THIS1]] 62 63 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* returned %this) unnamed_addr 64 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 65 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] 66 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] 67 // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AD2Ev( 68 // CHECK: ret [[A]]* [[THIS1]] 69 } 70 71 // Awkward virtual cases. 72 namespace test2 { 73 void foo(); 74 75 struct A { 76 int x; 77 78 A(int); 79 virtual ~A() { foo(); } 80 }; 81 82 struct B { 83 int y; 84 int z; 85 86 B(int); 87 virtual ~B() { foo(); } 88 }; 89 90 struct C : A, virtual B { 91 int q; 92 93 C(int i) : A(i), B(i) { foo(); } 94 ~C() { foo(); } 95 }; 96 97 void test() { 98 C c = 10; 99 } 100 101 // Tests at eof 102 } 103 104 namespace test3 { 105 struct A { 106 int x; 107 ~A(); 108 }; 109 110 void a() { 111 // CHECK-LABEL: define void @_ZN5test31aEv() 112 // CHECK: call noalias i8* @_Znam(i32 48) 113 // CHECK: store i32 4 114 // CHECK: store i32 10 115 A *x = new A[10]; 116 } 117 118 void b(int n) { 119 // CHECK-LABEL: define void @_ZN5test31bEi( 120 // CHECK: [[N:%.*]] = load i32* 121 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) 122 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 123 // CHECK: [[OR:%.*]] = or i1 124 // CHECK: [[SZ:%.*]] = select i1 [[OR]] 125 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 126 // CHECK: store i32 4 127 // CHECK: store i32 [[N]] 128 A *x = new A[n]; 129 } 130 131 void c() { 132 // CHECK-LABEL: define void @_ZN5test31cEv() 133 // CHECK: call noalias i8* @_Znam(i32 808) 134 // CHECK: store i32 4 135 // CHECK: store i32 200 136 A (*x)[20] = new A[10][20]; 137 } 138 139 void d(int n) { 140 // CHECK-LABEL: define void @_ZN5test31dEi( 141 // CHECK: [[N:%.*]] = load i32* 142 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 143 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 144 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 145 // CHECK: [[SZ:%.*]] = select 146 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 147 // CHECK: store i32 4 148 // CHECK: store i32 [[NE]] 149 A (*x)[20] = new A[n][20]; 150 } 151 152 void e(A *x) { 153 // CHECK-LABEL: define void @_ZN5test31eEPNS_1AE( 154 // CHECK: icmp eq {{.*}}, null 155 // CHECK: getelementptr {{.*}}, i64 -8 156 // CHECK: getelementptr {{.*}}, i64 4 157 // CHECK: bitcast {{.*}} to i32* 158 // CHECK: load 159 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 160 // CHECK: call void @_ZdaPv 161 delete [] x; 162 } 163 164 void f(A (*x)[20]) { 165 // CHECK-LABEL: define void @_ZN5test31fEPA20_NS_1AE( 166 // CHECK: icmp eq {{.*}}, null 167 // CHECK: getelementptr {{.*}}, i64 -8 168 // CHECK: getelementptr {{.*}}, i64 4 169 // CHECK: bitcast {{.*}} to i32* 170 // CHECK: load 171 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 172 // CHECK: call void @_ZdaPv 173 delete [] x; 174 } 175 } 176 177 namespace test4 { 178 struct A { 179 int x; 180 void operator delete[](void *, size_t sz); 181 }; 182 183 void a() { 184 // CHECK-LABEL: define void @_ZN5test41aEv() 185 // CHECK: call noalias i8* @_Znam(i32 48) 186 // CHECK: store i32 4 187 // CHECK: store i32 10 188 A *x = new A[10]; 189 } 190 191 void b(int n) { 192 // CHECK-LABEL: define void @_ZN5test41bEi( 193 // CHECK: [[N:%.*]] = load i32* 194 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) 195 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 196 // CHECK: [[SZ:%.*]] = select 197 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 198 // CHECK: store i32 4 199 // CHECK: store i32 [[N]] 200 A *x = new A[n]; 201 } 202 203 void c() { 204 // CHECK-LABEL: define void @_ZN5test41cEv() 205 // CHECK: call noalias i8* @_Znam(i32 808) 206 // CHECK: store i32 4 207 // CHECK: store i32 200 208 A (*x)[20] = new A[10][20]; 209 } 210 211 void d(int n) { 212 // CHECK-LABEL: define void @_ZN5test41dEi( 213 // CHECK: [[N:%.*]] = load i32* 214 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 215 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 216 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 217 // CHECK: [[SZ:%.*]] = select 218 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 219 // CHECK: store i32 4 220 // CHECK: store i32 [[NE]] 221 A (*x)[20] = new A[n][20]; 222 } 223 224 void e(A *x) { 225 // CHECK-LABEL: define void @_ZN5test41eEPNS_1AE( 226 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 227 // CHECK: getelementptr inbounds {{.*}}, i64 4 228 // CHECK: bitcast 229 // CHECK: [[T0:%.*]] = load i32* 230 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 231 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 232 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 233 delete [] x; 234 } 235 236 void f(A (*x)[20]) { 237 // CHECK-LABEL: define void @_ZN5test41fEPA20_NS_1AE( 238 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 239 // CHECK: getelementptr inbounds {{.*}}, i64 4 240 // CHECK: bitcast 241 // CHECK: [[T0:%.*]] = load i32* 242 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 243 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 244 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 245 delete [] x; 246 } 247 } 248 249 // <rdar://problem/8386802>: don't crash 250 namespace test5 { 251 struct A { 252 ~A(); 253 }; 254 255 // CHECK-LABEL: define void @_ZN5test54testEPNS_1AE 256 void test(A *a) { 257 // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4 258 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4 259 // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4 260 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]]) 261 // CHECK-NEXT: ret void 262 a->~A(); 263 } 264 } 265 266 namespace test6 { 267 struct A { 268 virtual ~A(); 269 }; 270 271 // CHECK-LABEL: define void @_ZN5test64testEPNS_1AE 272 void test(A *a) { 273 // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4 274 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4 275 // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4 276 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null 277 // CHECK-NEXT: br i1 [[ISNULL]] 278 // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to void ([[A]]*)*** 279 // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)*** [[T0]] 280 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)** [[T1]], i64 1 281 // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)** [[T2]] 282 // CHECK-NEXT: call void [[T3]]([[A]]* [[V]]) 283 // CHECK-NEXT: br label 284 // CHECK: ret void 285 delete a; 286 } 287 } 288 289 namespace test7 { 290 int foo(); 291 292 // Static and guard tested at top of file 293 294 // CHECK-LABEL: define void @_ZN5test74testEv() 295 void test() { 296 // CHECK: [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 1 297 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 298 // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0 299 // CHECK-NEXT: br i1 [[T2]] 300 // -> fallthrough, end 301 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x) 302 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 303 // CHECK-NEXT: br i1 [[T4]] 304 // -> fallthrough, end 305 // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv() 306 // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4 307 // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x) 308 // CHECK-NEXT: br label 309 // -> end 310 // end: 311 // CHECK: ret void 312 static int x = foo(); 313 314 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 315 // CHECK-NEXT: cleanup 316 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) 317 // CHECK: resume { i8*, i32 } 318 } 319 } 320 321 namespace test8 { 322 struct A { 323 A(); 324 ~A(); 325 }; 326 327 // Static and guard tested at top of file 328 329 // CHECK-LABEL: define void @_ZN5test84testEv() 330 void test() { 331 // CHECK: [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 1 332 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 333 // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0 334 // CHECK-NEXT: br i1 [[T2]] 335 // -> fallthrough, end 336 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x) 337 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 338 // CHECK-NEXT: br i1 [[T4]] 339 // -> fallthrough, end 340 // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x) 341 342 // FIXME: Here we register a global destructor that 343 // unconditionally calls the destructor. That's what we've always 344 // done for -fno-use-cxa-atexit here, but that's really not 345 // semantically correct at all. 346 347 // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x) 348 // CHECK-NEXT: br label 349 // -> end 350 // end: 351 // CHECK: ret void 352 static A x; 353 354 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 355 // CHECK-NEXT: cleanup 356 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) 357 // CHECK: resume { i8*, i32 } 358 } 359 } 360 361 // rdar://12836470 362 // Use a larger-than-mandated array cookie when allocating an 363 // array whose type is overaligned. 364 namespace test9 { 365 class __attribute__((aligned(16))) A { 366 float data[4]; 367 public: 368 A(); 369 ~A(); 370 }; 371 372 A *testNew(unsigned n) { 373 return new A[n]; 374 } 375 // CHECK: define [[TEST9:%.*]]* @_ZN5test97testNewEj(i32 376 // CHECK: [[N_VAR:%.*]] = alloca i32, align 4 377 // CHECK: [[N:%.*]] = load i32* [[N_VAR]], align 4 378 // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 16) 379 // CHECK-NEXT: [[O0:%.*]] = extractvalue { i32, i1 } [[T0]], 1 380 // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 0 381 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 16) 382 // CHECK-NEXT: [[O1:%.*]] = extractvalue { i32, i1 } [[T2]], 1 383 // CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]] 384 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 385 // CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]] 386 // CHECK-NEXT: [[ALLOC:%.*]] = call noalias i8* @_Znam(i32 [[T4]]) 387 // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[ALLOC]] to i32* 388 // CHECK-NEXT: store i32 16, i32* [[T0]] 389 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32* [[T0]], i32 1 390 // CHECK-NEXT: store i32 [[N]], i32* [[T1]] 391 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8* [[ALLOC]], i64 16 392 // CHECK-NEXT: bitcast i8* [[T0]] to [[TEST9]]* 393 // Array allocation follows. 394 395 void testDelete(A *array) { 396 delete[] array; 397 } 398 // CHECK-LABEL: define void @_ZN5test910testDeleteEPNS_1AE( 399 // CHECK: [[BEGIN:%.*]] = load [[TEST9]]** 400 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], null 401 // CHECK-NEXT: br i1 [[T0]], 402 // CHECK: [[T0:%.*]] = bitcast [[TEST9]]* [[BEGIN]] to i8* 403 // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -16 404 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8* [[ALLOC]], i64 4 405 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32* 406 // CHECK-NEXT: [[N:%.*]] = load i32* [[T1]] 407 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9]]* [[BEGIN]], i32 [[N]] 408 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], [[END]] 409 // CHECK-NEXT: br i1 [[T0]], 410 // Array deallocation follows. 411 } 412 413 // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev( 414 // CHECK: call [[C]]* @_ZN5test21CD1Ev( 415 // CHECK: ret [[C]]* undef 416 417 // CHECK-LABEL: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev( 418 // CHECK: call void @_ZN5test21CD0Ev( 419 // CHECK: ret void 420