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