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

llvm-svn: 284624
This commit is contained in:
Hans Wennborg 2016-10-19 18:04:27 +00:00
parent a85154518f
commit 0a79a1203a
2 changed files with 23 additions and 9 deletions

View File

@ -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;

View File

@ -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