brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.8 KiB · 7276e56 Raw
411 lines · cpp
1// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++98 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s2// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++11 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s3 4// CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 45// CHECK: @_ZGVZN5test74testEvE1x = internal global i32 06// CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 17// CHECK: @_ZGVZN5test84testEvE1x = internal global i32 08 9typedef typeof(sizeof(int)) size_t;10 11class foo {12public:13    foo();14    virtual ~foo();15};16 17class bar : public foo {18public:19	bar();20};21 22// The global dtor needs the right calling conv with -fno-use-cxa-atexit23bar baz;24 25// PR959326// Make sure atexit(3) is used for global dtors.27 28// CHECK:      call ptr @_ZN3barC1Ev(29// CHECK-NEXT: call i32 @atexit(ptr @__dtor_baz)30 31// CHECK-NOT: @_GLOBAL__D_a()32// CHECK-LABEL: define internal void @__dtor_baz()33// CHECK: call ptr @_ZN3barD1Ev(ptr @baz)34 35// Destructors and constructors must return this.36namespace 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 148    // CHECK: call ptr @_ZN5test11AC1Ei(ptr {{[^,]*}} [[AV]], i32 10)49    // CHECK: invoke void @_ZN5test11A3barEv(ptr {{[^,]*}} [[AV]])50    // CHECK: call ptr @_ZN5test11AD1Ev(ptr {{[^,]*}} [[AV]])51    // CHECK: ret void52    A a = 10;53    a.bar();54  }55 56  // CHECK: define linkonce_odr ptr @_ZN5test11AC1Ei(ptr {{[^,]*}} returned {{[^,]*}} %this, i32 %i) unnamed_addr57  // CHECK:   [[THIS:%.*]] = alloca ptr, align 458  // CHECK:   store ptr {{.*}}, ptr [[THIS]]59  // CHECK:   [[THIS1:%.*]] = load ptr, ptr [[THIS]]60  // CHECK:   {{%.*}} = call ptr @_ZN5test11AC2Ei(61  // CHECK:   ret ptr [[THIS1]]62 63  // CHECK: define linkonce_odr ptr @_ZN5test11AD1Ev(ptr {{[^,]*}} returned {{[^,]*}} %this) unnamed_addr64  // CHECK:   [[THIS:%.*]] = alloca ptr, align 465  // CHECK:   store ptr {{.*}}, ptr [[THIS]]66  // CHECK:   [[THIS1:%.*]] = load ptr, ptr [[THIS]]67  // CHECK:   {{%.*}} = call ptr @_ZN5test11AD2Ev(68  // CHECK:   ret ptr [[THIS1]]69}70 71// Awkward virtual cases.72namespace 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 eof102}103 104namespace test3 {105  struct A {106    int x;107    ~A();108  };109 110  void a() {111    // CHECK-LABEL: define{{.*}} void @_ZN5test31aEv()112    // CHECK: call noalias nonnull ptr @_Znam(i32 48)113    // CHECK: store i32 4114    // CHECK: store i32 10115    A *x = new A[10];116  }117 118  void b(int n) {119    // CHECK-LABEL: define{{.*}} void @_ZN5test31bEi(120    // CHECK: [[N:%.*]] = load i32, ptr121    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)122    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)123    // CHECK: [[OR:%.*]] = or i1124    // CHECK: [[SZ:%.*]] = select i1 [[OR]]125    // CHECK: call noalias nonnull ptr @_Znam(i32 [[SZ]])126    // CHECK: store i32 4127    // 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 nonnull ptr @_Znam(i32 808)134    // CHECK: store i32 4135    // CHECK: store i32 200136    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, ptr142    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)143    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20144    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)145    // CHECK: [[SZ:%.*]] = select146    // CHECK: call noalias nonnull ptr @_Znam(i32 [[SZ]])147    // CHECK: store i32 4148    // 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 {{.*}}, null155    // CHECK: getelementptr {{.*}}, i32 -8156    // CHECK: getelementptr {{.*}}, i32 4157    // CHECK: load158    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev159    // CHECK11: call {{.*}} @_ZN5test31AD1Ev160    // CHECK: call void @_ZdaPv161    delete [] x;162  }163 164  void f(A (*x)[20]) {165    // CHECK-LABEL: define{{.*}} void @_ZN5test31fEPA20_NS_1AE(166    // CHECK: icmp eq {{.*}}, null167    // CHECK: getelementptr {{.*}}, i32 -8168    // CHECK: getelementptr {{.*}}, i32 4169    // CHECK: load170    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev171    // CHECK11: call {{.*}} @_ZN5test31AD1Ev172    // CHECK: call void @_ZdaPv173    delete [] x;174  }175}176 177namespace 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 nonnull ptr @_Znam(i32 48)186    // CHECK: store i32 4187    // CHECK: store i32 10188    A *x = new A[10];189  }190 191  void b(int n) {192    // CHECK-LABEL: define{{.*}} void @_ZN5test41bEi(193    // CHECK: [[N:%.*]] = load i32, ptr194    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)195    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)196    // CHECK: [[SZ:%.*]] = select197    // CHECK: call noalias nonnull ptr @_Znam(i32 [[SZ]])198    // CHECK: store i32 4199    // 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 nonnull ptr @_Znam(i32 808)206    // CHECK: store i32 4207    // CHECK: store i32 200208    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, ptr214    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)215    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20216    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)217    // CHECK: [[SZ:%.*]] = select218    // CHECK: call noalias nonnull ptr @_Znam(i32 [[SZ]])219    // CHECK: store i32 4220    // 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 {{.*}}, i32 -8227    // CHECK: getelementptr inbounds {{.*}}, i32 4228    // CHECK: [[T0:%.*]] = load i32, ptr229    // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]230    // CHECK: [[T2:%.*]] = add i32 [[T1]], 8231    // CHECK: call void @_ZN5test41AdaEPvm(ptr [[ALLOC]], i32 [[T2]])232    delete [] x;233  }234 235  void f(A (*x)[20]) {236    // CHECK-LABEL: define{{.*}} void @_ZN5test41fEPA20_NS_1AE(237    // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i32 -8238    // CHECK: getelementptr inbounds {{.*}}, i32 4239    // CHECK: [[T0:%.*]] = load i32, ptr240    // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]241    // CHECK: [[T2:%.*]] = add i32 [[T1]], 8242    // CHECK: call void @_ZN5test41AdaEPvm(ptr [[ALLOC]], i32 [[T2]])243    delete [] x;244  }245}246 247namespace test5 {248  struct A {249    ~A();250  };251 252  // CHECK-LABEL: define{{.*}} void @_ZN5test54testEPNS_1AE253  void test(A *a) {254    // CHECK:      [[PTR:%.*]] = alloca ptr, align 4255    // CHECK-NEXT: store ptr {{.*}}, ptr [[PTR]], align 4256    // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr [[PTR]], align 4257    // CHECK-NEXT: call ptr @_ZN5test51AD1Ev(ptr {{[^,]*}} [[TMP]])258    // CHECK-NEXT: ret void259    a->~A();260  }261}262 263namespace test6 {264  struct A {265    virtual ~A();266  };267 268  // CHECK-LABEL: define{{.*}} void @_ZN5test64testEPNS_1AE269  void test(A *a) {270    // CHECK:      [[AVAR:%.*]] = alloca ptr, align 4271    // CHECK-NEXT: store ptr {{.*}}, ptr [[AVAR]], align 4272    // CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[AVAR]], align 4273    // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[V]], null274    // CHECK-NEXT: br i1 [[ISNULL]]275    // CHECK: [[T1:%.*]] = load ptr, ptr [[V]]276    // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds ptr, ptr [[T1]], i64 1277    // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T2]]278    // CHECK-NEXT: call void [[T3]](ptr {{[^,]*}} [[V]])279    // CHECK-NEXT: br label280    // CHECK:      ret void281    delete a;282  }283}284 285namespace test7 {286  int foo();287 288  // Static and guard tested at top of file289 290  // CHECK-LABEL: define{{.*}} void @_ZN5test74testEv() {{.*}} personality ptr @__gxx_personality_v0291  void test() {292    // CHECK:      [[T0:%.*]] = load atomic i8, ptr @_ZGVZN5test74testEvE1x acquire, align 4293    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1294    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0295    // CHECK-NEXT: br i1 [[T2]]296    //   -> fallthrough, end297    // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZN5test74testEvE1x)298    // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0299    // CHECK-NEXT: br i1 [[T4]]300    //   -> fallthrough, end301    // CHECK:      [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv()302    // CHECK:      store i32 [[INIT]], ptr @_ZZN5test74testEvE1x, align 4303    // CHECK-NEXT: call void @__cxa_guard_release(ptr @_ZGVZN5test74testEvE1x)304    // CHECK-NEXT: br label305    //   -> end306    // end:307    // CHECK:      ret void308    static int x = foo();309 310    // CHECK:      landingpad { ptr, i32 }311    // CHECK-NEXT:   cleanup312    // CHECK:      call void @__cxa_guard_abort(ptr @_ZGVZN5test74testEvE1x)313    // CHECK:      resume { ptr, i32 }314  }315}316 317namespace test8 {318  struct A {319    A();320    ~A();321  };322 323  // Static and guard tested at top of file324 325  // CHECK-LABEL: define{{.*}} void @_ZN5test84testEv() {{.*}} personality ptr @__gxx_personality_v0326  void test() {327    // CHECK:      [[T0:%.*]] = load atomic i8, ptr @_ZGVZN5test84testEvE1x acquire, align 4328    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1329    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0330    // CHECK-NEXT: br i1 [[T2]]331    //   -> fallthrough, end332    // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZN5test84testEvE1x)333    // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0334    // CHECK-NEXT: br i1 [[T4]]335    //   -> fallthrough, end336    // CHECK:      [[INIT:%.*]] = invoke ptr @_ZN5test81AC1Ev(ptr {{[^,]*}} @_ZZN5test84testEvE1x)337 338    // FIXME: Here we register a global destructor that339    // unconditionally calls the destructor.  That's what we've always340    // done for -fno-use-cxa-atexit here, but that's really not341    // semantically correct at all.342 343    // CHECK:      call void @__cxa_guard_release(ptr @_ZGVZN5test84testEvE1x)344    // CHECK-NEXT: br label345    //   -> end346    // end:347    // CHECK:      ret void348    static A x;349 350    // CHECK:      landingpad { ptr, i32 }351    // CHECK-NEXT:   cleanup352    // CHECK:      call void @__cxa_guard_abort(ptr @_ZGVZN5test84testEvE1x)353    // CHECK:      resume { ptr, i32 }354  }355}356 357// Use a larger-than-mandated array cookie when allocating an358// array whose type is overaligned.359namespace test9 {360  class __attribute__((aligned(16))) A {361    float data[4];362  public:363    A();364    ~A();365  };366 367  A *testNew(unsigned n) {368    return new A[n];369  }370// CHECK:    define{{.*}} ptr @_ZN5test97testNewEj(i32371// CHECK:      [[N_VAR:%.*]] = alloca i32, align 4372// CHECK:      [[N:%.*]] = load i32, ptr [[N_VAR]], align 4373// CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 16)374// CHECK-NEXT: [[O0:%.*]] = extractvalue { i32, i1 } [[T0]], 1375// CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 0376// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 16)377// CHECK-NEXT: [[O1:%.*]] = extractvalue { i32, i1 } [[T2]], 1378// CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]]379// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0380// CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]]381// CHECK-NEXT: [[ALLOC:%.*]] = call noalias nonnull ptr @_Znam(i32 [[T4]])382// CHECK-NEXT: store i32 16, ptr [[ALLOC]]383// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32, ptr [[ALLOC]], i32 1384// CHECK-NEXT: store i32 [[N]], ptr [[T1]]385// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, ptr [[ALLOC]], i32 16386//   Array allocation follows.387 388  void testDelete(A *array) {389    delete[] array;390  }391// CHECK-LABEL:    define{{.*}} void @_ZN5test910testDeleteEPNS_1AE(392// CHECK:      [[BEGIN:%.*]] = load ptr, ptr393// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[BEGIN]], null394// CHECK-NEXT: br i1 [[T0]],395// CHECK: [[ALLOC:%.*]] = getelementptr inbounds i8, ptr [[BEGIN]], i32 -16396// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, ptr [[ALLOC]], i32 4397// CHECK-NEXT: [[N:%.*]] = load i32, ptr [[T0]]398// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9:%.*]], ptr [[BEGIN]], i32 [[N]]399// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[BEGIN]], [[END]]400// CHECK-NEXT: br i1 [[T0]],401//   Array deallocation follows.402}403 404  // CHECK: define linkonce_odr ptr @_ZTv0_n12_N5test21CD1Ev(405  // CHECK:   call ptr @_ZN5test21CD1Ev(406  // CHECK:   ret ptr undef407 408  // CHECK-LABEL: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(409  // CHECK:   call void @_ZN5test21CD0Ev(410  // CHECK:   ret void411