brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 92d4560 Raw
197 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK,NULL-INVALID2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK,NULL-VALID3 4struct Member { int x; Member(); Member(int); Member(const Member &); };5struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };6 7struct ValueClass {8  ValueClass(int x, int y) : x(x), y(y) {}9  int x;10  int y;11}; // subject to ABI trickery12 13 14 15/* Test basic functionality. */16struct A {17  A(struct Undeclared &);18  A(ValueClass);19  Member mem;20};21 22A::A(struct Undeclared &ref) : mem(0) {}23 24// Check that delegation works.25// NULL-INVALID-LABEL: define{{.*}} void @_ZN1AC2ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef nonnull align 1 %ref) unnamed_addr26// NULL-VALID-LABEL: define{{.*}} void @_ZN1AC2ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef align 1 %ref) unnamed_addr27// CHECK: call void @_ZN6MemberC1Ei(28 29// NULL-INVALID-LABEL: define{{.*}} void @_ZN1AC1ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef nonnull align 1 %ref) unnamed_addr30// NULL-VALID-LABEL: define{{.*}} void @_ZN1AC1ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef align 1 %ref) unnamed_addr31// CHECK: call void @_ZN1AC2ER10Undeclared(32 33A::A(ValueClass v) : mem(v.y - v.x) {}34 35// CHECK-LABEL: define{{.*}} void @_ZN1AC2E10ValueClass(ptr {{[^,]*}} %this, i64 %v.coerce) unnamed_addr36// CHECK: call void @_ZN6MemberC1Ei(37 38// CHECK-LABEL: define{{.*}} void @_ZN1AC1E10ValueClass(ptr {{[^,]*}} %this, i64 %v.coerce) unnamed_addr39// CHECK: call void @_ZN1AC2E10ValueClass(40 41/* Test that things work for inheritance. */42struct B : A {43  B(struct Undeclared &);44  Member mem;45};46 47B::B(struct Undeclared &ref) : A(ref), mem(1) {}48 49// NULL-INVALID-LABEL: define{{.*}} void @_ZN1BC2ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef nonnull align 1 %ref) unnamed_addr50// NULL-VALID-LABEL: define{{.*}} void @_ZN1BC2ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef align 1 %ref) unnamed_addr51// CHECK: call void @_ZN1AC2ER10Undeclared(52// CHECK: call void @_ZN6MemberC1Ei(53 54// NULL-INVALID-LABEL: define{{.*}} void @_ZN1BC1ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef nonnull align 1 %ref) unnamed_addr55// NULL-VALID-LABEL: define{{.*}} void @_ZN1BC1ER10Undeclared(ptr {{[^,]*}} %this, ptr noundef align 1 %ref) unnamed_addr56// CHECK: call void @_ZN1BC2ER10Undeclared(57 58 59/* Test that the delegation optimization is disabled for classes with60   virtual bases (for now).  This is necessary because a vbase61   initializer could access one of the parameter variables by62   reference.  That's a solvable problem, but let's not solve it right63   now. */64struct C : virtual A {65  C(int);66  Member mem;67};68C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}69 70// CHECK-LABEL: define{{.*}} void @_ZN1CC2Ei(ptr {{[^,]*}} %this, ptr noundef %vtt, i32 noundef %x) unnamed_addr71// CHECK: call void @_ZN6MemberC1Ei(72 73// CHECK-LABEL: define{{.*}} void @_ZN1CC1Ei(ptr {{[^,]*}} %this, i32 noundef %x) unnamed_addr74// CHECK: call void @_ZN10ValueClassC1Eii(75// CHECK: call void @_ZN1AC2E10ValueClass(76// CHECK: call void @_ZN6MemberC1Ei(77 78 79/* Test that the delegation optimization is disabled for varargs80   constructors. */81struct D : A {82  D(int, ...);83  Member mem;84};85 86D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}87 88// CHECK-LABEL: define{{.*}} void @_ZN1DC2Eiz(ptr {{[^,]*}} %this, i32 noundef %x, ...) unnamed_addr89// CHECK: call void @_ZN10ValueClassC1Eii(90// CHECK: call void @_ZN1AC2E10ValueClass(91// CHECK: call void @_ZN6MemberC1Ei(92 93// CHECK-LABEL: define{{.*}} void @_ZN1DC1Eiz(ptr {{[^,]*}} %this, i32 noundef %x, ...) unnamed_addr94// CHECK: call void @_ZN10ValueClassC1Eii(95// CHECK: call void @_ZN1AC2E10ValueClass(96// CHECK: call void @_ZN6MemberC1Ei(97 98// PR6622:  this shouldn't crash99namespace test0 {100  struct A {};101  struct B : virtual A { int x; };102  struct C : B {};103 104  void test(C &in) {105    C tmp = in;106  }107}108 109namespace test1 {110  struct A { A(); void *ptr; };111  struct B { B(); int x; A a[0]; };112  B::B() {}113  // CHECK-LABEL:    define{{.*}} void @_ZN5test11BC2Ev(114  // CHECK:      [[THIS:%.*]] = load ptr, ptr115  // CHECK-NEXT: ret void116}117 118// Ensure that we119// a) emit the ABI-required but useless complete object and deleting destructor120//    symbols for an abstract class, and121// b) do *not* emit references to virtual base destructors for an abstract class122//123// Our approach to this is to give these functions a body that simply traps.124//125// FIXME: We should ideally not create these symbols at all, but Clang can126// actually generate references to them in other TUs in some cases, so we can't127// stop emitting them without breaking ABI. See:128//129//   https://github.com/itanium-cxx-abi/cxx-abi/issues/10130namespace abstract {131  // Note, the destructor of this class is not instantiated here.132  template<typename T> struct should_not_appear_in_output {133    ~should_not_appear_in_output() { int arr[-(int)sizeof(T)]; }134  };135 136  struct X { ~X(); };137 138  struct A : virtual should_not_appear_in_output<int>, X {139    virtual ~A() = 0;140  };141 142  // CHECK-LABEL: define{{.*}} void @_ZN8abstract1AD2Ev(143  // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(144  // CHECK: ret145 146  // CHECK-LABEL: define{{.*}} void @_ZN8abstract1AD1Ev(147  // CHECK: call {{.*}}@llvm.trap(148  // CHECK: unreachable149 150  // CHECK-LABEL: define{{.*}} void @_ZN8abstract1AD0Ev(151  // CHECK: call {{.*}}@llvm.trap(152  // CHECK: unreachable153  A::~A() {}154 155  struct B : virtual should_not_appear_in_output<int>, X {156    virtual void f() = 0;157    ~B();158  };159 160  // CHECK-LABEL: define{{.*}} void @_ZN8abstract1BD2Ev(161  // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(162  // CHECK: ret163 164  // CHECK-LABEL: define{{.*}} void @_ZN8abstract1BD1Ev(165  // CHECK: call {{.*}}@llvm.trap(166  // CHECK: unreachable167 168  // CHECK-NOT: @_ZN8abstract1BD0Ev(169  B::~B() {}170}171 172namespace redecl {173  struct A {174    A();175  };176  class A;177 178  // CHECK-LABEL: define{{.*}} void @_ZN6redecl1AC2Ev(179  // CHECK:       define{{.*}} void @_ZN6redecl1AC1Ev(180  // CHECK:       call {{.*}} @_ZN6redecl1AC2Ev(181  A::A() {}182}183 184namespace fwdecl {185  struct A;186  struct A {187    int v;188  };189  struct B : A {190    B() = default;191    B(int);192  };193  struct C : B {};194 195  void f() { C{}; }196}197