Home | History | Annotate | Download | only in CodeGenCXX
      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