r269271 - [MS ABI] Don't crash when zero-initializing a vbase which contains a vbase

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Wed May 11 20:51:52 PDT 2016


Author: majnemer
Date: Wed May 11 22:51:52 2016
New Revision: 269271

URL: http://llvm.org/viewvc/llvm-project?rev=269271&view=rev
Log:
[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.

Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=269271&r1=269270&r2=269271&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed May 11 22:51:52 2016
@@ -370,6 +370,9 @@ static void EmitNullBaseClassInitializat
   std::vector<CharUnits> VBPtrOffsets =
       CGF.CGM.getCXXABI().getVBPtrOffsets(Base);
   for (CharUnits VBPtrOffset : VBPtrOffsets) {
+    // Stop before we hit any virtual base pointers located in virtual bases.
+    if (VBPtrOffset >= NVSize)
+      break;
     std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
     CharUnits LastStoreOffset = LastStore.first;
     CharUnits LastStoreSize = LastStore.second;

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=269271&r1=269270&r2=269271&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Wed May 11 22:51:52 2016
@@ -499,3 +499,25 @@ void callit(C *p) {
 // CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
 // CHECK: call x86_thiscallcc void @"\01?g at 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 at test6@@AAE at 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)
+}




More information about the cfe-commits mailing list