r192875 - Follow-up to r192822: fix Clang assertion when building with -fexceptions
Timur Iskhodzhanov
timurrrr at google.com
Thu Oct 17 02:11:45 PDT 2013
Author: timurrrr
Date: Thu Oct 17 04:11:45 2013
New Revision: 192875
URL: http://llvm.org/viewvc/llvm-project?rev=192875&view=rev
Log:
Follow-up to r192822: fix Clang assertion when building with -fexceptions
Modified:
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-exceptions.cpp
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192875&r1=192874&r2=192875&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Oct 17 04:11:45 2013
@@ -587,14 +587,20 @@ llvm::Value *MicrosoftCXXABI::adjustThis
bool AvoidVirtualOffset = false;
if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) {
// A base destructor can only be called from a complete destructor of the
- // same record type or another destructor of a more derived type.
+ // same record type or another destructor of a more derived type;
+ // or a constructor of the same record type if an exception is thrown.
+ assert(isa<CXXDestructorDecl>(CGF.CurGD.getDecl()) ||
+ isa<CXXConstructorDecl>(CGF.CurGD.getDecl()));
const CXXRecordDecl *CurRD =
- cast<CXXDestructorDecl>(CGF.CurGD.getDecl())->getParent();
+ cast<CXXMethodDecl>(CGF.CurGD.getDecl())->getParent();
if (MD->getParent() == CurRD) {
- assert(CGF.CurGD.getDtorType() == Dtor_Complete);
- // We're calling the main base dtor from a complete dtor, so we know the
- // "this" offset statically.
+ if (isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
+ assert(CGF.CurGD.getDtorType() == Dtor_Complete);
+ if (isa<CXXConstructorDecl>(CGF.CurGD.getDecl()))
+ assert(CGF.CurGD.getCtorType() == Ctor_Complete);
+ // We're calling the main base dtor from a complete structor,
+ // so we know the "this" offset statically.
AvoidVirtualOffset = true;
} else {
// Let's see if we try to call a destructor of a non-virtual base.
@@ -604,6 +610,8 @@ llvm::Value *MicrosoftCXXABI::adjustThis
continue;
// If we call a base destructor for a non-virtual base, we statically
// know where it expects the vfptr and "this" to be.
+ // The total offset should reflect the adjustment done by
+ // adjustThisParameterInVirtualFunctionPrologue().
AvoidVirtualOffset = true;
break;
}
@@ -613,7 +621,6 @@ llvm::Value *MicrosoftCXXABI::adjustThis
if (AvoidVirtualOffset) {
const ASTRecordLayout &Layout =
CGF.getContext().getASTRecordLayout(MD->getParent());
- // This reflects the logic from VFTableBuilder::ComputeThisOffset().
StaticOffset += Layout.getVBaseClassOffset(ML.VBase);
} else {
This = CGF.Builder.CreateBitCast(This, charPtrTy);
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-exceptions.cpp?rev=192875&r1=192874&r2=192875&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-exceptions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-exceptions.cpp Thu Oct 17 04:11:45 2013
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft -fexceptions | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft -fexceptions -fno-rtti | FileCheck -check-prefix WIN32 %s
struct A {
A();
@@ -116,3 +116,42 @@ int HasConditionalDeactivatedCleanups(bo
// WIN32: br i1 %[[isactive]]
// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"(%struct.A* %[[arg1]])
// WIN32: }
+
+namespace crash_on_partial_destroy {
+struct A {
+ virtual ~A();
+};
+
+struct B : virtual A {
+ // Has an implicit destructor.
+};
+
+struct C : B {
+ C();
+};
+
+void foo();
+// We used to crash when emitting this.
+C::C() { foo(); }
+
+// Verify that we don't bother with a vbtable lookup when adjusting the this
+// pointer to call a base destructor from a constructor while unwinding.
+// WIN32-LABEL: define {{.*}} @"\01??0C at crash_on_partial_destroy@@QAE at XZ"{{.*}} {
+// WIN32: landingpad
+//
+// We shouldn't do any vbptr loads, just constant GEPs.
+// WIN32-NOT: load
+// WIN32: getelementptr inbounds i8* %{{.*}}, i64 4
+// WIN32-NOT: load
+// WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::B"*
+// WIN32: invoke x86_thiscallcc void @"\01??1B at crash_on_partial_destroy@@UAE at XZ"
+//
+// WIN32-NOT: load
+// WIN32: bitcast %"struct.crash_on_partial_destroy::C"* %{{.*}} to i8*
+// WIN32-NOT: load
+// WIN32: getelementptr inbounds i8* %{{.*}}, i64 4
+// WIN32-NOT: load
+// WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"*
+// WIN32: invoke x86_thiscallcc void @"\01??1A at crash_on_partial_destroy@@UAE at XZ"
+// WIN32: }
+}
More information about the cfe-commits
mailing list