arm.cpp revision 93c332a8ba2c193c435b293966d343dab15f555b
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 [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr 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 [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr 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: [[OR:%.*]] = or i1 121 // CHECK: [[SZ:%.*]] = select i1 [[OR]] 122 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 123 // CHECK: store i32 4 124 // CHECK: store i32 [[N]] 125 A *x = new A[n]; 126 } 127 128 void c() { 129 // CHECK: define void @_ZN5test31cEv() 130 // CHECK: call noalias i8* @_Znam(i32 808) 131 // CHECK: store i32 4 132 // CHECK: store i32 200 133 A (*x)[20] = new A[10][20]; 134 } 135 136 void d(int n) { 137 // CHECK: define void @_ZN5test31dEi( 138 // CHECK: [[N:%.*]] = load i32* 139 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 140 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 141 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 142 // CHECK: [[SZ:%.*]] = select 143 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 144 // CHECK: store i32 4 145 // CHECK: store i32 [[NE]] 146 A (*x)[20] = new A[n][20]; 147 } 148 149 void e(A *x) { 150 // CHECK: define void @_ZN5test31eEPNS_1AE( 151 // CHECK: icmp eq {{.*}}, null 152 // CHECK: getelementptr {{.*}}, i64 -8 153 // CHECK: getelementptr {{.*}}, i64 4 154 // CHECK: bitcast {{.*}} to i32* 155 // CHECK: load 156 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 157 // CHECK: call void @_ZdaPv 158 delete [] x; 159 } 160 161 void f(A (*x)[20]) { 162 // CHECK: define void @_ZN5test31fEPA20_NS_1AE( 163 // CHECK: icmp eq {{.*}}, null 164 // CHECK: getelementptr {{.*}}, i64 -8 165 // CHECK: getelementptr {{.*}}, i64 4 166 // CHECK: bitcast {{.*}} to i32* 167 // CHECK: load 168 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev 169 // CHECK: call void @_ZdaPv 170 delete [] x; 171 } 172} 173 174namespace test4 { 175 struct A { 176 int x; 177 void operator delete[](void *, size_t sz); 178 }; 179 180 void a() { 181 // CHECK: define void @_ZN5test41aEv() 182 // CHECK: call noalias i8* @_Znam(i32 48) 183 // CHECK: store i32 4 184 // CHECK: store i32 10 185 A *x = new A[10]; 186 } 187 188 void b(int n) { 189 // CHECK: define void @_ZN5test41bEi( 190 // CHECK: [[N:%.*]] = load i32* 191 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) 192 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 193 // CHECK: [[SZ:%.*]] = select 194 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 195 // CHECK: store i32 4 196 // CHECK: store i32 [[N]] 197 A *x = new A[n]; 198 } 199 200 void c() { 201 // CHECK: define void @_ZN5test41cEv() 202 // CHECK: call noalias i8* @_Znam(i32 808) 203 // CHECK: store i32 4 204 // CHECK: store i32 200 205 A (*x)[20] = new A[10][20]; 206 } 207 208 void d(int n) { 209 // CHECK: define void @_ZN5test41dEi( 210 // CHECK: [[N:%.*]] = load i32* 211 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) 212 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 213 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) 214 // CHECK: [[SZ:%.*]] = select 215 // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) 216 // CHECK: store i32 4 217 // CHECK: store i32 [[NE]] 218 A (*x)[20] = new A[n][20]; 219 } 220 221 void e(A *x) { 222 // CHECK: define void @_ZN5test41eEPNS_1AE( 223 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 224 // CHECK: getelementptr inbounds {{.*}}, i64 4 225 // CHECK: bitcast 226 // CHECK: [[T0:%.*]] = load i32* 227 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 228 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 229 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 230 delete [] x; 231 } 232 233 void f(A (*x)[20]) { 234 // CHECK: define void @_ZN5test41fEPA20_NS_1AE( 235 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 236 // CHECK: getelementptr inbounds {{.*}}, i64 4 237 // CHECK: bitcast 238 // CHECK: [[T0:%.*]] = load i32* 239 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] 240 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 241 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) 242 delete [] x; 243 } 244} 245 246// <rdar://problem/8386802>: don't crash 247namespace test5 { 248 struct A { 249 ~A(); 250 }; 251 252 // CHECK: define void @_ZN5test54testEPNS_1AE 253 void test(A *a) { 254 // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4 255 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4 256 // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4 257 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]]) 258 // CHECK-NEXT: ret void 259 a->~A(); 260 } 261} 262 263namespace test6 { 264 struct A { 265 virtual ~A(); 266 }; 267 268 // CHECK: define void @_ZN5test64testEPNS_1AE 269 void test(A *a) { 270 // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4 271 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4 272 // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4 273 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null 274 // CHECK-NEXT: br i1 [[ISNULL]] 275 // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)*** 276 // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]] 277 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1 278 // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]] 279 // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]]) 280 // CHECK-NEXT: br label 281 // CHECK: ret void 282 delete a; 283 } 284} 285 286namespace test7 { 287 int foo(); 288 289 // Static and guard tested at top of file 290 291 // CHECK: define void @_ZN5test74testEv() 292 void test() { 293 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x 294 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 295 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 296 // CHECK-NEXT: br i1 [[T2]] 297 // -> fallthrough, end 298 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x) 299 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 300 // CHECK-NEXT: br i1 [[T4]] 301 // -> fallthrough, end 302 // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv() 303 // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4 304 // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x) 305 // CHECK-NEXT: br label 306 // -> end 307 // end: 308 // CHECK: ret void 309 static int x = foo(); 310 311 // CHECK: call i8* @llvm.eh.exception() 312 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) 313 // CHECK: call void @llvm.eh.resume( 314 } 315} 316 317namespace test8 { 318 struct A { 319 A(); 320 ~A(); 321 }; 322 323 // Static and guard tested at top of file 324 325 // CHECK: define void @_ZN5test84testEv() 326 void test() { 327 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x 328 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1 329 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 330 // CHECK-NEXT: br i1 [[T2]] 331 // -> fallthrough, end 332 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x) 333 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0 334 // CHECK-NEXT: br i1 [[T4]] 335 // -> fallthrough, end 336 // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_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(i32* @_ZGVZN5test84testEvE1x) 344 // CHECK-NEXT: br label 345 // -> end 346 // end: 347 // CHECK: ret void 348 static A x; 349 350 // CHECK: call i8* @llvm.eh.exception() 351 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) 352 // CHECK: call void @llvm.eh.resume( 353 } 354} 355 356 // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev( 357 // CHECK: call [[C]]* @_ZN5test21CD1Ev( 358 // CHECK: ret [[C]]* undef 359 360 // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev( 361 // CHECK: call void @_ZN5test21CD0Ev( 362 // CHECK: ret void 363 364// CHECK: @_GLOBAL__D_a() 365// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz) 366