diff options
Diffstat (limited to 'clang/test/CodeGenCXX/microsoft-abi-structors.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-structors.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp index 19fff5dd6a3..85b9a7df63c 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -3,6 +3,8 @@ // vftables are emitted very late, so do another pass to try to keep the checks // in source order. // RUN: FileCheck --check-prefix DTORS %s < %t +// RUN: FileCheck --check-prefix DTORS2 %s < %t +// RUN: FileCheck --check-prefix DTORS3 %s < %t // // RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti | FileCheck --check-prefix DTORS-X64 %s @@ -121,6 +123,79 @@ void use_D() { D c; } } // end namespace basic +namespace dtor_in_second_nvbase { + +struct A { + virtual void f(); // A needs vftable to be primary. +}; +struct B { + virtual ~B(); +}; +struct C : A, B { + virtual ~C(); +}; + +C::~C() { +// CHECK-LABEL: define x86_thiscallcc void @"\01??1C@dtor_in_second_nvbase@@UAE@XZ" +// CHECK: (%"struct.dtor_in_second_nvbase::C"* %this) +// No this adjustment! +// CHECK-NOT: getelementptr +// CHECK: load %"struct.dtor_in_second_nvbase::C"** %{{.*}} +// Now we this-adjust before calling ~B. +// CHECK: bitcast %"struct.dtor_in_second_nvbase::C"* %{{.*}} to i8* +// CHECK: getelementptr inbounds i8* %{{.*}}, i64 4 +// CHECK: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::B"* +// CHECK: call x86_thiscallcc void @"\01??1B@dtor_in_second_nvbase@@UAE@XZ" +// CHECK: (%"struct.dtor_in_second_nvbase::B"* %{{.*}}) +// CHECK: ret void +} + +void foo() { + C c; +} +// DTORS2-LABEL: define weak x86_thiscallcc void @"\01??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z" +// DTORS2: (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete) +// Do an adjustment from B* to C*. +// DTORS2: getelementptr i8* %{{.*}}, i32 -4 +// DTORS2: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::C"* +// DTORS2: call x86_thiscallcc void @"\01??_GC@dtor_in_second_nvbase@@UAEPAXI@Z" +// DTORS2: ret void + +} + +namespace test2 { +// Just like dtor_in_second_nvbase, except put that in a vbase of a diamond. + +// C's dtor is in the non-primary base. +struct A { virtual void f(); }; +struct B { virtual ~B(); }; +struct C : A, B { virtual ~C(); int c; }; + +// Diamond hierarchy, with C as the shared vbase. +struct D : virtual C { int d; }; +struct E : virtual C { int e; }; +struct F : D, E { ~F(); int f; }; + +F::~F() { +// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*) +// Do an adjustment from C vbase subobject to F as though F was the +// complete type. +// CHECK: getelementptr inbounds i8* %{{.*}}, i32 -20 +// CHECK: bitcast i8* %{{.*}} to %"struct.test2::F"* +// CHECK: store %"struct.test2::F"* +} + +void foo() { + F f; +} +// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@UAE@XZ" +// Do an adjustment from C* to F*. +// DTORS3: getelementptr i8* %{{.*}}, i32 20 +// DTORS3: bitcast i8* %{{.*}} to %"struct.test2::F"* +// DTORS3: call x86_thiscallcc void @"\01??1F@test2@@UAE@XZ" +// DTORS3: ret void + +} namespace constructors { |