diff options
author | Timur Iskhodzhanov <timurrrr@google.com> | 2013-10-17 09:11:45 +0000 |
---|---|---|
committer | Timur Iskhodzhanov <timurrrr@google.com> | 2013-10-17 09:11:45 +0000 |
commit | 406a479ddb5c55394f7bb8866416146d22535484 (patch) | |
tree | f13fd4d2bf6447620ec7e44007728a08dfad77c3 | |
parent | 333112a4397deba64c73e9f255ce0d320360dc0f (diff) | |
download | bcm5719-llvm-406a479ddb5c55394f7bb8866416146d22535484.tar.gz bcm5719-llvm-406a479ddb5c55394f7bb8866416146d22535484.zip |
Follow-up to r192822: fix Clang assertion when building with -fexceptions
llvm-svn: 192875
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 19 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-exceptions.cpp | 41 |
2 files changed, 53 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index c1ea60d09a4..a8e074c7b37 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -587,14 +587,20 @@ llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualCall( 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::adjustThisArgumentForVirtualCall( 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::adjustThisArgumentForVirtualCall( 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); diff --git a/clang/test/CodeGenCXX/microsoft-abi-exceptions.cpp b/clang/test/CodeGenCXX/microsoft-abi-exceptions.cpp index 383270a1f2e..c95adcd8eeb 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-exceptions.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-exceptions.cpp @@ -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(bool cond) { // WIN32: br i1 %[[isactive]] // WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@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@crash_on_partial_destroy@@QAE@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@crash_on_partial_destroy@@UAE@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@crash_on_partial_destroy@@UAE@XZ" +// WIN32: } +} |