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