summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-05-12 03:51:52 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-05-12 03:51:52 +0000
commitfe581ebfbabbdcd9c910690005aefe0804cb4b19 (patch)
treeb529193cd073a5000a9d5f0c58bcf419ddcbff2b /test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
parentcf9fe978839aa983f5bd41a0987f5a8eea1fad87 (diff)
[MS ABI] Don't crash when zero-initializing a vbase which contains a vbase
Bases can be zero-initialized: the storage is zero-initialized before the base constructor is run. The MS ABI has a quirk where base VBPtrs are not installed by the base constructor but by the most derived class. In particular, they are installed before the base constructor is run. The derived constructor must be careful to zero-initialize only the bits of the class which haven't already been populated by virtual base pointers. While we correctly avoided this scenario, we didn't handle the case where the base class has virtual bases which have virtual bases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269271 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp')
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 7d13a393c4..480ae8cfbb 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -499,3 +499,25 @@ void callit(C *p) {
// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
// CHECK: call x86_thiscallcc void @"\01?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]])
}
+
+namespace test6 {
+class A {};
+class B : virtual A {};
+class C : virtual B {
+ virtual void m_fn1();
+ float field;
+};
+class D : C {
+ D();
+};
+D::D() : C() {}
+// CHECK-LABEL: define x86_thiscallcc %"class.test6::D"* @"\01??0D@test6@@AAE@XZ"(
+// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
+// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+
+// CHECK: %[[SKIP_VBASES]]
+// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
+// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
+// CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false)
+}