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