[CodeGen] Fix an assert in EmitNullConstant.

r235815 changed CGRecordLowering::accumulateBases to ignore non-virtual
bases of size 0, which prevented adding those non-virtual bases to
CGRecordLayout's NonVirtualBases. This caused clang to assert when
CGRecordLayout::getNonVirtualBaseLLVMFieldNo was called in
EmitNullConstant. This commit fixes the bug by ignoring zero-sized
non-virtual bases in EmitNullConstant.

rdar://problem/28100139

Differential Revision: https://reviews.llvm.org/D24312

llvm-svn: 281405
This commit is contained in:
Akira Hatanaka 2016-09-13 22:13:02 +00:00
parent d33b4a6292
commit 255abad9b1
2 changed files with 23 additions and 1 deletions

View File

@ -1532,7 +1532,8 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
// Ignore empty bases. // Ignore empty bases.
if (base->isEmpty()) if (base->isEmpty() ||
CGM.getContext().getASTRecordLayout(base).getNonVirtualSize().isZero())
continue; continue;
unsigned fieldIndex = layout.getNonVirtualBaseLLVMFieldNo(base); unsigned fieldIndex = layout.getNonVirtualBaseLLVMFieldNo(base);

View File

@ -96,3 +96,24 @@ namespace rdar20621065 {
// Type checked at the top of the file. // Type checked at the top of the file.
B b; B b;
}; };
// This test used to crash when CGRecordLayout::getNonVirtualBaseLLVMFieldNo was called.
namespace record_layout {
struct X0 {
int x[0];
};
template<typename>
struct X2 : X0 {
};
template<typename>
struct X3 : X2<int> {
X3() : X2<int>() {}
};
void test0() {
X3<int>();
}
}