summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorTimur Iskhodzhanov <timurrrr@google.com>2014-03-20 20:38:34 +0000
committerTimur Iskhodzhanov <timurrrr@google.com>2014-03-20 20:38:34 +0000
commitba5570221da15ae0954efabbd9f017c8c438ab44 (patch)
treeebd0a262cc255a642896bd44458a5e119e37c116 /clang/test
parent46357931ab7c07c1a43a64959284cab6e1697333 (diff)
downloadbcm5719-llvm-ba5570221da15ae0954efabbd9f017c8c438ab44.tar.gz
bcm5719-llvm-ba5570221da15ae0954efabbd9f017c8c438ab44.zip
Fix PR19172 - wrong this adjustment calculated for virtual destructor in a class with complex inheritance
Reviewed at http://llvm-reviews.chandlerc.com/D3128 llvm-svn: 204394
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp42
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp25
2 files changed, 67 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 22e1fa71ecd..23cc70994b6 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -377,3 +377,45 @@ void D::bar() {
// CHECK: ret
}
}
+
+namespace test4{
+// PR19172: We used to merge method vftable locations wrong.
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B {
+ virtual ~B() {}
+};
+
+struct C : virtual A, B {
+ virtual ~C();
+};
+
+void foo(void*);
+
+C::~C() {
+ // CHECK-LABEL: define x86_thiscallcc void @"\01??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this)
+
+ // In this case "this" points to the most derived class, so no GEPs needed.
+ // CHECK-NOT: getelementptr
+ // CHECK-NOT: bitcast
+ // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to [1 x i8*]**
+ // CHECK: store [1 x i8*]* @"\01??_7C@test4@@6BB@1@@", [1 x i8*]** %[[VFPTR_i8]]
+
+ foo(this);
+}
+
+void destroy(C *obj) {
+ // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj)
+
+ delete obj;
+ // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to void (%"struct.test4::C"*, i32)***
+ // CHECK: %[[VFTABLE:.*]] = load void (%"struct.test4::C"*, i32)*** %[[VPTR]]
+ // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds void (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
+ // CHECK: %[[VFUN:.*]] = load void (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
+ // CHECK: call x86_thiscallcc void %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1)
+}
+
+}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index 82eac8a047a..5e05d151365 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -21,6 +21,7 @@
// RUN: FileCheck --check-prefix=VDTORS-U %s < %t
// RUN: FileCheck --check-prefix=VDTORS-V %s < %t
// RUN: FileCheck --check-prefix=VDTORS-P %s < %t
+// RUN: FileCheck --check-prefix=VDTORS-R %s < %t
// RUN: FileCheck --check-prefix=RET-W %s < %t
// RUN: FileCheck --check-prefix=RET-T %s < %t
// RUN: FileCheck --check-prefix=RET-V %s < %t
@@ -543,6 +544,30 @@ struct P : T, Y {
P p;
+struct Q {
+ virtual ~Q();
+};
+
+// PR19172: Yet another diamond we miscompiled.
+struct R : virtual Q, X {
+ // VDTORS-R: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
+ // VDTORS-R-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ // VDTORS-R-NEXT: [this adjustment: -8 non-virtual]
+
+ // VDTORS-R: Thunks for 'vdtors::R::~R()' (1 entry).
+ // VDTORS-R-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // VDTORS-R: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
+ // VDTORS-R-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ // VDTORS-R-NEXT: 1 | void vdtors::X::zzz()
+
+ // VDTORS-R: VFTable indices for 'vdtors::R' (1 entry).
+ // VDTORS-R-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ virtual ~R();
+};
+
+R r;
+
}
namespace return_adjustment {
OpenPOWER on IntegriCloud