Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
      2 
      3 void t1(int *a) {
      4   delete a;
      5 }
      6 
      7 struct S {
      8   int a;
      9 };
     10 
     11 // POD types.
     12 void t3(S *s) {
     13   delete s;
     14 }
     15 
     16 // Non-POD
     17 struct T {
     18   ~T();
     19   int a;
     20 };
     21 
     22 // CHECK: define void @_Z2t4P1T
     23 void t4(T *t) {
     24   // CHECK: call void @_ZN1TD1Ev
     25   // CHECK-NEXT: bitcast
     26   // CHECK-NEXT: call void @_ZdlPv
     27   delete t;
     28 }
     29 
     30 // PR5102
     31 template <typename T>
     32 class A {
     33   public: operator T *() const;
     34 };
     35 
     36 void f() {
     37   A<char*> a;
     38 
     39   delete a;
     40 }
     41 
     42 namespace test0 {
     43   struct A {
     44     void *operator new(__SIZE_TYPE__ sz);
     45     void operator delete(void *p) { ::operator delete(p); }
     46     ~A() {}
     47   };
     48 
     49   // CHECK: define void @_ZN5test04testEPNS_1AE(
     50   void test(A *a) {
     51     // CHECK: call void @_ZN5test01AD1Ev
     52     // CHECK-NEXT: bitcast
     53     // CHECK-NEXT: call void @_ZN5test01AdlEPv
     54     delete a;
     55   }
     56 
     57   // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr
     58   // CHECK: define linkonce_odr void @_ZN5test01AdlEPv
     59 }
     60 
     61 namespace test1 {
     62   struct A {
     63     int x;
     64     ~A();
     65   };
     66 
     67   // CHECK: define void @_ZN5test14testEPA10_A20_NS_1AE(
     68   void test(A (*arr)[10][20]) {
     69     delete [] arr;
     70     // CHECK:      icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null
     71     // CHECK-NEXT: br i1
     72 
     73     // CHECK:      [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0
     74     // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8*
     75     // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -8
     76     // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64*
     77     // CHECK-NEXT: [[COUNT:%.*]] = load i64* [[T1]]
     78     // CHECK:      [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[COUNT]]
     79     // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]]
     80     // CHECK-NEXT: br i1 [[ISEMPTY]],
     81     // CHECK:      [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
     82     // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1
     83     // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]])
     84     // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
     85     // CHECK-NEXT: br i1 [[ISDONE]]
     86     // CHECK:      call void @_ZdaPv(i8* [[ALLOC]])
     87   }
     88 }
     89 
     90 namespace test2 {
     91   // CHECK: define void @_ZN5test21fEPb
     92   void f(bool *b) {
     93     // CHECK: call void @_ZdlPv(i8*
     94     delete b;
     95     // CHECK: call void @_ZdaPv(i8*
     96     delete [] b;
     97   }
     98 }
     99 
    100 namespace test3 {
    101   void f(int a[10][20]) {
    102     // CHECK: call void @_ZdaPv(i8*
    103     delete a;
    104   }
    105 }
    106 
    107 namespace test4 {
    108   // PR10341: ::delete with a virtual destructor
    109   struct X {
    110     virtual ~X();
    111     void operator delete (void *);
    112   };
    113 
    114   // CHECK: define void @_ZN5test421global_delete_virtualEPNS_1XE
    115   void global_delete_virtual(X *xp) {
    116     //   Load the offset-to-top from the vtable and apply it.
    117     //   This has to be done first because the dtor can mess it up.
    118     // CHECK:      [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64**
    119     // CHECK-NEXT: [[VTABLE:%.*]] = load i64** [[T0]]
    120     // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64* [[VTABLE]], i64 -2
    121     // CHECK-NEXT: [[OFFSET:%.*]] = load i64* [[T0]], align 8
    122     // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8*
    123     // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]]
    124     //   Load the complete-object destructor (not the deleting destructor)
    125     //   and call it.
    126     // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)***
    127     // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)*** [[T0]]
    128     // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)** [[VTABLE]], i64 0
    129     // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)** [[T0]]
    130     // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]])
    131     //   Call the global operator delete.
    132     // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) [[NUW:#[0-9]+]]
    133     ::delete xp;
    134   }
    135 }
    136 
    137 namespace test5 {
    138   struct Incomplete;
    139   // CHECK: define void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_
    140   void array_delete_incomplete(Incomplete *p1, Incomplete *p2) {
    141     // CHECK: call void @_ZdlPv
    142     delete p1;
    143     // CHECK: call void @_ZdaPv
    144     delete [] p2;
    145   }
    146 }
    147 
    148 // CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}
    149