brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 21b9f8c Raw
177 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSIZE2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - -Oz -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-SIZE3 4void t1(int *a) {5  delete a;6}7 8struct S {9  int a;10};11 12// POD types.13 14// CHECK-LABEL: define{{.*}} void @_Z2t3P1S15void t3(S *s) {16  // CHECK: icmp {{.*}} null17  // CHECK: br i118 19  // CHECK: call void @_ZdlPvm20 21  // Check the delete is inside the 'if !null' check unless we're optimizing22  // for size. FIXME: We could omit the branch entirely in this case.23  // CHECK-NOSIZE-NEXT: br24  // CHECK-SIZE-NEXT: ret25  delete s;26}27 28// Non-POD29struct T {30  ~T();31  int a;32};33 34// CHECK-LABEL: define{{.*}} void @_Z2t4P1T35void t4(T *t) {36  // CHECK: call void @_ZN1TD1Ev37  // CHECK-SIZE-NEXT: br38  // CHECK: call void @_ZdlPvm39  delete t;40}41 42// PR510243template <typename T>44class A {45  public: operator T *() const;46};47 48void f() {49  A<char*> a;50  51  delete a;52}53 54namespace test0 {55  struct A {56    void *operator new(__SIZE_TYPE__ sz);57    void operator delete(void *p) { ::operator delete(p); }58    ~A() {}59  };60 61  // CHECK-LABEL: define{{.*}} void @_ZN5test04testEPNS_1AE(62  void test(A *a) {63    // CHECK: call void @_ZN5test01AD1Ev64    // CHECK-SIZE-NEXT: br65    // CHECK: call void @_ZN5test01AdlEPv66    delete a;67  }68 69  // CHECK-LABEL: define linkonce_odr void @_ZN5test01AD1Ev(ptr {{[^,]*}} %this) unnamed_addr70  // CHECK-LABEL: define linkonce_odr void @_ZN5test01AdlEPv71}72 73namespace test1 {74  struct A {75    int x;76    ~A();77  };78 79  // CHECK-LABEL: define{{.*}} void @_ZN5test11fEPA10_A20_NS_1AE(80  void f(A (*arr)[10][20]) {81    delete [] arr;82    // CHECK:      icmp eq ptr [[PTR:%.*]], null83    // CHECK-NEXT: br i184 85    // CHECK:      [[ALLOC:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 -886    // CHECK-NEXT: [[COUNT:%.*]] = load i64, ptr [[ALLOC]]87    // CHECK:      [[END:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[PTR]], i64 [[COUNT]]88    // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq ptr [[PTR]], [[END]]89    // CHECK-NEXT: br i1 [[ISEMPTY]],90    // CHECK:      [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]91    // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], ptr [[PAST]], i64 -192    // CHECK-NEXT: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[CUR]])93    // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq ptr [[CUR]], [[PTR]]94    // CHECK-NEXT: br i1 [[ISDONE]]95    // CHECK:      [[MUL:%.*]] = mul i64 4, [[COUNT]]96    // CHECK-NEXT: [[SIZE:%.*]] = add i64 [[MUL]], 897    // CHECK-NEXT: call void @_ZdaPvm(ptr noundef [[ALLOC]], i64 noundef [[SIZE]])98  }99 100  // CHECK-LABEL: define{{.*}} void @_ZN5test11gEPA_NS_1AE(101  void g(A (*arr)[]) {102    delete [] arr;103    // CHECK:      icmp eq ptr [[PTR:%.*]], null104    // CHECK-NEXT: br i1105 106    // CHECK:      [[ALLOC:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 -8107    // CHECK-NEXT: [[COUNT:%.*]] = load i64, ptr [[ALLOC]]108    // CHECK:      [[END:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[PTR]], i64 [[COUNT]]109    // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq ptr [[PTR]], [[END]]110    // CHECK-NEXT: br i1 [[ISEMPTY]],111    // CHECK:      [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]112    // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], ptr [[PAST]], i64 -1113    // CHECK-NEXT: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[CUR]])114    // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq ptr [[CUR]], [[PTR]]115    // CHECK-NEXT: br i1 [[ISDONE]]116    // CHECK:      call void @_ZdaPv(ptr noundef [[ALLOC]])117  }118}119 120namespace test2 {121  // CHECK-LABEL: define{{.*}} void @_ZN5test21fEPb122  void f(bool *b) {123    // CHECK: call void @_ZdlPvm(ptr{{.*}}i64124    delete b;125    // CHECK: call void @_ZdaPv(ptr126    delete [] b;127  }128}129 130namespace test3 {131  void f(int a[10][20]) {132    // CHECK: call void @_ZdaPv(ptr133    delete a;134  }135}136 137namespace test4 {138  // PR10341: ::delete with a virtual destructor139  struct X {140    virtual ~X();141    void operator delete (void *);142  };143 144  // CHECK-LABEL: define{{.*}} void @_ZN5test421global_delete_virtualEPNS_1XE145  void global_delete_virtual(X *xp) {146    //   Load the offset-to-top from the vtable and apply it.147    //   This has to be done first because the dtor can mess it up.148    // CHECK: [[XP:%.*]] = load ptr, ptr [[XP_ADDR:%.*]]149    // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[XP]]150    // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64, ptr [[VTABLE]], i64 -2151    // CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr [[T0]], align 8152    // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8, ptr [[XP]], i64 [[OFFSET]]153    //   Load the complete-object destructor (not the deleting destructor)154    //   and call noundef it.155    // CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[XP:%.*]]156    // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0157    // CHECK-NEXT: [[DTOR:%.*]] = load ptr, ptr [[T0]]158    // CHECK-NEXT: call void [[DTOR]](ptr {{[^,]*}} [[OBJ:%.*]])159    //   Call the global operator delete.160    // CHECK-NEXT: call void @_ZdlPvm(ptr noundef [[ALLOCATED]], i64 noundef 8) [[NUW:#[0-9]+]]161    ::delete xp;162  }163}164 165namespace test5 {166  struct Incomplete;167  // CHECK-LABEL: define{{.*}} void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_168  void array_delete_incomplete(Incomplete *p1, Incomplete *p2) {169    // CHECK: call void @_ZdlPv170    delete p1;171    // CHECK: call void @_ZdaPv172    delete [] p2;173  }174}175 176// CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}177