r199160 - [ms-abi] Always generate complete constructors in the Microsoft C++ ABI
Reid Kleckner
reid at kleckner.net
Mon Jan 13 14:57:31 PST 2014
Author: rnk
Date: Mon Jan 13 16:57:31 2014
New Revision: 199160
URL: http://llvm.org/viewvc/llvm-project?rev=199160&view=rev
Log:
[ms-abi] Always generate complete constructors in the Microsoft C++ ABI
Fixes PR18435, where we generated a base ctor instead of a complete
ctor, and so failed to construct virtual bases when constructing the
complete object.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=199160&r1=199159&r2=199160&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Mon Jan 13 16:57:31 2014
@@ -190,11 +190,13 @@ bool CodeGenModule::TryEmitDefinitionAsA
void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
CXXCtorType ctorType) {
- // The complete constructor is equivalent to the base constructor
- // for classes with no virtual bases. Try to emit it as an alias.
- if (getTarget().getCXXABI().hasConstructorVariants() &&
- !ctor->getParent()->getNumVBases() &&
- (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+ if (!getTarget().getCXXABI().hasConstructorVariants()) {
+ // If there are no constructor variants, always emit the complete destructor.
+ ctorType = Ctor_Complete;
+ } else if (!ctor->getParent()->getNumVBases() &&
+ (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+ // The complete constructor is equivalent to the base constructor
+ // for classes with no virtual bases. Try to emit it as an alias.
bool ProducedAlias =
!TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete),
GlobalDecl(ctor, Ctor_Base), true);
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=199160&r1=199159&r2=199160&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Jan 13 16:57:31 2014
@@ -699,6 +699,10 @@ void CodeGenFunction::EmitConstructorBod
const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
CXXCtorType CtorType = CurGD.getCtorType();
+ assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
+ CtorType == Ctor_Complete) &&
+ "can only generate complete ctor for this ABI");
+
// Before we go any further, try the complete->base constructor
// delegation optimization.
if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
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=199160&r1=199159&r2=199160&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Mon Jan 13 16:57:31 2014
@@ -312,3 +312,30 @@ D::~D() {
}
}
+
+namespace test2 {
+struct A { A(); };
+struct B : virtual A { B() {} };
+struct C : B, A { C() {} };
+
+// PR18435: Order mattered here. We were generating code for the delegating
+// call to B() from C().
+void callC() { C x; }
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::C"* @"\01??0C at test2@@QAE at XZ"
+// CHECK: (%"struct.test2::C"* returned %this, i32 %is_most_derived)
+// CHECK: br i1
+// Virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A at test2@@QAE at XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: br label
+// Non-virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::B"* @"\01??0B at test2@@QAE at XZ"(%"struct.test2::B"* %{{.*}}, i32 0)
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A at test2@@QAE at XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: ret
+
+// CHECK2-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::B"* @"\01??0B at test2@@QAE at XZ"
+// CHECK2: (%"struct.test2::B"* returned %this, i32 %is_most_derived)
+// CHECK2: call x86_thiscallcc %"struct.test2::A"* @"\01??0A at test2@@QAE at XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK2: ret
+
+}
More information about the cfe-commits
mailing list