Home | History | Annotate | Download | only in CodeGenCXX
      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:   [[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.
     69 namespace 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 
    101 namespace 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 
    174 namespace 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
    247 namespace 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 
    263 namespace 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 
    286 namespace 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:      landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
    312     // CHECK-NEXT:   cleanup
    313     // CHECK:      call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
    314     // CHECK:      resume { i8*, i32 }
    315   }
    316 }
    317 
    318 namespace test8 {
    319   struct A {
    320     A();
    321     ~A();
    322   };
    323 
    324   // Static and guard tested at top of file
    325 
    326   // CHECK: define void @_ZN5test84testEv()
    327   void test() {
    328     // CHECK:      [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x
    329     // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
    330     // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
    331     // CHECK-NEXT: br i1 [[T2]]
    332     //   -> fallthrough, end
    333     // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
    334     // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
    335     // CHECK-NEXT: br i1 [[T4]]
    336     //   -> fallthrough, end
    337     // CHECK:      [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
    338 
    339     // FIXME: Here we register a global destructor that
    340     // unconditionally calls the destructor.  That's what we've always
    341     // done for -fno-use-cxa-atexit here, but that's really not
    342     // semantically correct at all.
    343 
    344     // CHECK:      call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x)
    345     // CHECK-NEXT: br label
    346     //   -> end
    347     // end:
    348     // CHECK:      ret void
    349     static A x;
    350 
    351     // CHECK:      landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
    352     // CHECK-NEXT:   cleanup
    353     // CHECK:      call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
    354     // CHECK:      resume { i8*, i32 }
    355   }
    356 }
    357 
    358   // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
    359   // CHECK:   call [[C]]* @_ZN5test21CD1Ev(
    360   // CHECK:   ret [[C]]* undef
    361 
    362   // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
    363   // CHECK:   call void @_ZN5test21CD0Ev(
    364   // CHECK:   ret void
    365 
    366 // CHECK: @_GLOBAL__D_a()
    367 // CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
    368