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