From: Hans Wennborg Date: Wed, 19 Oct 2016 18:04:27 +0000 (+0000) Subject: MS ABI: Fix assert when generating virtual function call with virtual bases and ... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8bd12ac7941aee16def56b2bf0d6d39d8c2aaa7b;p=clang MS ABI: Fix assert when generating virtual function call with virtual bases and -flto (PR30731) getClassAtVTableLocation() was calling ASTRecordLayout::getBaseClassOffset() on a virtual base, causing an assert. Differential Revision: https://reviews.llvm.org/D25779 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284624 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 2708ddec72..37ba3f969a 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1773,15 +1773,8 @@ static const CXXRecordDecl *getClassAtVTableLocation(ASTContext &Ctx, CharUnits MaxBaseOffset; for (auto &&B : RD->bases()) { const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl(); - CharUnits BaseOffset = Layout.getBaseClassOffset(Base); - if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) { - MaxBase = Base; - MaxBaseOffset = BaseOffset; - } - } - for (auto &&B : RD->vbases()) { - const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl(); - CharUnits BaseOffset = Layout.getVBaseClassOffset(Base); + CharUnits BaseOffset = B.isVirtual() ? Layout.getVBaseClassOffset(Base) + : Layout.getBaseClassOffset(Base); if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) { MaxBase = Base; MaxBaseOffset = BaseOffset; diff --git a/test/CodeGenCXX/pr30731.cpp b/test/CodeGenCXX/pr30731.cpp new file mode 100644 index 0000000000..078f21ceda --- /dev/null +++ b/test/CodeGenCXX/pr30731.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm -flto -std=c++11 -o - %s | FileCheck %s + +struct A { + virtual ~A(); +}; + +struct B {}; + +struct C { + virtual void f(); +}; + +struct S : A, virtual B, C { + void f() override; +}; + +void f(S* s) { s->f(); } + +// CHECK-LABEL: define void @"\01?f@@YAXPAUS@@@Z" +// CHECK: call +// CHECK: ret void