1 // RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -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 // Checked at end of file. 24 bar baz; 25 26 // Destructors and constructors must return this. 27 namespace test1 { 28 void foo(); 29 30 struct A { 31 A(int i) { foo(); } 32 ~A() { foo(); } 33 void bar() { foo(); } 34 }; 35 36 // CHECK: define void @_ZN5test14testEv() 37 void test() { 38 // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1 39 // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10) 40 // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]]) 41 // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]]) 42 // CHECK: ret void 43 A a = 10; 44 a.bar(); 45 } 46 47 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr 48 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 49 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] 50 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] 51 // CHECK: call [[A]]* @_ZN5test11AC2Ei( 52 // CHECK: ret [[A]]* [[THIS1]] 53 54 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr 55 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 56 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] 57 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] 58 // CHECK: call [[A]]* @_ZN5test11AD2Ev( 59 // CHECK: ret [[A]]* [[THIS1]] 60 } 61 62 // Awkward virtual cases. 63 namespace test2 { 64 void foo(); 65 66 struct A { 67 int x; 68 69 A(int); 70 virtual ~A() { foo(); } 71 }; 72 73 struct B { 74 int y; 75 int z; 76 77 B(int); 78 virtual ~B() { foo(); } 79 }; 80 81 struct C : A, virtual B { 82 int q; 83 84 C(int i) : A(i), B(i) { foo(); } 85 ~C() { foo(); } 86 }; 87 88 void test() { 89 C c = 10; 90 } 91 92 // Tests at eof 93 } 94 95 namespace test3 { 96 struct A { 97 int x; 98 ~A(); 99 }; 100 101 void a() { 102 // CHECK: define void @_ZN5test31aEv() 103 // CHECK: call noalias i8* @_Znam(i32 48) 104 // CHECK: store i32 4 105 // CHECK: store i32 10 106 A *x = new A[10]; 107 } 108 109 void b(int n) { 110 // CHECK: define void @_ZN5test31bEi( 111 // CHECK: [[N:%.*]] = load i32* 112 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) 113 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 114 // CHECK: [[OR:%.*]] = or i1 115 // CHECK: [[SZ:%.*]] = select i1 [[OR]] 116 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 117 // CHECK: store i32 4 118 // CHECK: store i32 [[N]] 119 A *x = new A[n]; 120 } 121 122 void c() { 123 // CHECK: define void @_ZN5test31cEv() 124 // CHECK: call noalias i8* @_Znam(i32 808) 125 // CHECK: store i32 4 126 // CHECK: store i32 200 127 A (*x)[20] = new A[10][20]; 128 } 129 130 void d(int n) { 131 // CHECK: define void @_ZN5test31dEi( 132 // CHECK: [[N:%.*]] = load i32* 133 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 134 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 135 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 136 // CHECK: [[SZ:%.*]] = select 137 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 138 // CHECK: store i32 4 139 // CHECK: store i32 [[NE]] 140 A (*x)[20] = new A[n][20]; 141 } 142 143 void e(A *x) { 144 // CHECK: define void @_ZN5test31eEPNS_1AE( 145 // CHECK: icmp eq {{.*}}, null 146 // CHECK: getelementptr {{.*}}, i64 -8 147 // CHECK: getelementptr {{.*}}, i64 4 148 // CHECK: bitcast {{.*}} to i32* 149 // CHECK: load 150 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 151 // CHECK: call void @_ZdaPv 152 delete [] x; 153 } 154 155 void f(A (*x)[20]) { 156 // CHECK: define void @_ZN5test31fEPA20_NS_1AE( 157 // CHECK: icmp eq {{.*}}, null 158 // CHECK: getelementptr {{.*}}, i64 -8 159 // CHECK: getelementptr {{.*}}, i64 4 160 // CHECK: bitcast {{.*}} to i32* 161 // CHECK: load 162 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 163 // CHECK: call void @_ZdaPv 164 delete [] x; 165 } 166 } 167 168 namespace test4 { 169 struct A { 170 int x; 171 void operator delete[](void *, size_t sz); 172 }; 173 174 void a() { 175 // CHECK: define void @_ZN5test41aEv() 176 // CHECK: call noalias i8* @_Znam(i32 48) 177 // CHECK: store i32 4 178 // CHECK: store i32 10 179 A *x = new A[10]; 180 } 181 182 void b(int n) { 183 // CHECK: define void @_ZN5test41bEi( 184 // CHECK: [[N:%.*]] = load i32* 185 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) 186 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 187 // CHECK: [[SZ:%.*]] = select 188 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 189 // CHECK: store i32 4 190 // CHECK: store i32 [[N]] 191 A *x = new A[n]; 192 } 193 194 void c() { 195 // CHECK: define void @_ZN5test41cEv() 196 // CHECK: call noalias i8* @_Znam(i32 808) 197 // CHECK: store i32 4 198 // CHECK: store i32 200 199 A (*x)[20] = new A[10][20]; 200 } 201 202 void d(int n) { 203 // CHECK: define void @_ZN5test41dEi( 204 // CHECK: [[N:%.*]] = load i32* 205 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 206 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 207 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 208 // CHECK: [[SZ:%.*]] = select 209 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 210 // CHECK: store i32 4 211 // CHECK: store i32 [[NE]] 212 A (*x)[20] = new A[n][20]; 213 } 214 215 void e(A *x) { 216 // CHECK: define void @_ZN5test41eEPNS_1AE( 217 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 218 // CHECK: getelementptr inbounds {{.*}}, i64 4 219 // CHECK: bitcast 220 // CHECK: [[T0:%.*]] = load i32* 221 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 222 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 223 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 224 delete [] x; 225 } 226 227 void f(A (*x)[20]) { 228 // CHECK: define void @_ZN5test41fEPA20_NS_1AE( 229 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 230 // CHECK: getelementptr inbounds {{.*}}, i64 4 231 // CHECK: bitcast 232 // CHECK: [[T0:%.*]] = load i32* 233 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 234 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 235 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 236 delete [] x; 237 } 238 } 239 240 // <rdar://problem/8386802>: don't crash 241 namespace test5 { 242 struct A { 243 ~A(); 244 }; 245 246 // CHECK: define void @_ZN5test54testEPNS_1AE 247 void test(A *a) { 248 // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4 249 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4 250 // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4 251 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]]) 252 // CHECK-NEXT: ret void 253 a->~A(); 254 } 255 } 256 257 namespace test6 { 258 struct A { 259 virtual ~A(); 260 }; 261 262 // CHECK: define void @_ZN5test64testEPNS_1AE 263 void test(A *a) { 264 // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4 265 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4 266 // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4 267 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null 268 // CHECK-NEXT: br i1 [[ISNULL]] 269 // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)*** 270 // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]] 271 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1 272 // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]] 273 // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]]) 274 // CHECK-NEXT: br label 275 // CHECK: ret void 276 delete a; 277 } 278 } 279 280 namespace test7 { 281 int foo(); 282 283 // Static and guard tested at top of file 284 285 // CHECK: define void @_ZN5test74testEv() 286 void test() { 287 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x 288 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 289 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 290 // CHECK-NEXT: br i1 [[T2]] 291 // -> fallthrough, end 292 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x) 293 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 294 // CHECK-NEXT: br i1 [[T4]] 295 // -> fallthrough, end 296 // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv() 297 // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4 298 // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x) 299 // CHECK-NEXT: br label 300 // -> end 301 // end: 302 // CHECK: ret void 303 static int x = foo(); 304 305 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 306 // CHECK-NEXT: cleanup 307 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) 308 // CHECK: resume { i8*, i32 } 309 } 310 } 311 312 namespace test8 { 313 struct A { 314 A(); 315 ~A(); 316 }; 317 318 // Static and guard tested at top of file 319 320 // CHECK: define void @_ZN5test84testEv() 321 void test() { 322 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x 323 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 324 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 325 // CHECK-NEXT: br i1 [[T2]] 326 // -> fallthrough, end 327 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x) 328 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 329 // CHECK-NEXT: br i1 [[T4]] 330 // -> fallthrough, end 331 // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x) 332 333 // FIXME: Here we register a global destructor that 334 // unconditionally calls the destructor. That's what we've always 335 // done for -fno-use-cxa-atexit here, but that's really not 336 // semantically correct at all. 337 338 // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x) 339 // CHECK-NEXT: br label 340 // -> end 341 // end: 342 // CHECK: ret void 343 static A x; 344 345 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 346 // CHECK-NEXT: cleanup 347 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) 348 // CHECK: resume { i8*, i32 } 349 } 350 } 351 352 // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev( 353 // CHECK: call [[C]]* @_ZN5test21CD1Ev( 354 // CHECK: ret [[C]]* undef 355 356 // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev( 357 // CHECK: call void @_ZN5test21CD0Ev( 358 // CHECK: ret void 359 360 // CHECK: @_GLOBAL__D_a() 361 // CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz) 362