Audit the code for places where it is assumed that every base specifier refers to a RecordType. Add assertions or conditions as appropriate. This fixes another crash in the Apache stdlib vector.

llvm-svn: 85055
This commit is contained in:
Sebastian Redl 2009-10-25 17:03:50 +00:00
parent c45c03c9dd
commit 1054faed32
7 changed files with 41 additions and 22 deletions

View File

@ -364,34 +364,36 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
} }
} }
} }
if (getNumBases() == 0 && getNumVBases() == 0) if (getNumBases() == 0 && getNumVBases() == 0)
return; return;
llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions; llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions;
if (!inTopClass) if (!inTopClass)
collectConversionFunctions(ConversionFunctions); collectConversionFunctions(ConversionFunctions);
for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(), for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(),
E = vbases_end(); VBase != E; ++VBase) { E = vbases_end(); VBase != E; ++VBase) {
CXXRecordDecl *VBaseClassDecl if (const RecordType *RT = VBase->getType()->getAs<RecordType>()) {
= cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); CXXRecordDecl *VBaseClassDecl
VBaseClassDecl->getNestedVisibleConversionFunctions(RD, = cast<CXXRecordDecl>(RT->getDecl());
TopConversionsTypeSet, VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
(inTopClass ? TopConversionsTypeSet : ConversionFunctions)); TopConversionsTypeSet,
(inTopClass ? TopConversionsTypeSet : ConversionFunctions));
}
} }
for (CXXRecordDecl::base_class_iterator Base = bases_begin(), for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
E = bases_end(); Base != E; ++Base) { E = bases_end(); Base != E; ++Base) {
if (Base->isVirtual()) if (Base->isVirtual())
continue; continue;
CXXRecordDecl *BaseClassDecl if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(RT->getDecl());
BaseClassDecl->getNestedVisibleConversionFunctions(RD,
TopConversionsTypeSet, BaseClassDecl->getNestedVisibleConversionFunctions(RD,
(inTopClass ? TopConversionsTypeSet : ConversionFunctions)); TopConversionsTypeSet,
(inTopClass ? TopConversionsTypeSet : ConversionFunctions));
}
} }
} }

View File

@ -47,6 +47,8 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) { e = RD->bases_end(); i != e; ++i) {
if (!i->isVirtual()) { if (!i->isVirtual()) {
assert(!i->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base = const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first. // Skip the PrimaryBase here, as it is laid down first.
@ -82,6 +84,8 @@ void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
// Now traverse all bases and find primary bases for them. // Now traverse all bases and find primary bases for them.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) { e = RD->bases_end(); i != e; ++i) {
assert(!i->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base = const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
@ -97,6 +101,8 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
const CXXRecordDecl *&FirstPrimary) { const CXXRecordDecl *&FirstPrimary) {
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) { e = RD->bases_end(); i != e; ++i) {
assert(!i->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base = const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (!i->isVirtual()) { if (!i->isVirtual()) {
@ -123,6 +129,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
// indirect bases, and record all their primary virtual base classes. // indirect bases, and record all their primary virtual base classes.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) { e = RD->bases_end(); i != e; ++i) {
assert(!i->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base = const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
IdentifyPrimaryBases(Base); IdentifyPrimaryBases(Base);
@ -173,6 +181,8 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) { e = RD->bases_end(); i != e; ++i) {
assert(!i->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base = const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
#if 0 #if 0
@ -235,6 +245,8 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
// Check bases. // Check bases.
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) { E = RD->bases_end(); I != E; ++I) {
assert(!I->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
if (I->isVirtual()) if (I->isVirtual())
continue; continue;
@ -305,6 +317,8 @@ void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
// Update bases. // Update bases.
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) { E = RD->bases_end(); I != E; ++I) {
assert(!I->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
if (I->isVirtual()) if (I->isVirtual())
continue; continue;

View File

@ -452,6 +452,8 @@ class RecordLayoutDumper : public ASTConsumer {
// Dump (non-virtual) bases // Dump (non-virtual) bases
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) { E = RD->bases_end(); I != E; ++I) {
assert(!I->getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
if (I->isVirtual()) if (I->isVirtual())
continue; continue;

View File

@ -5034,7 +5034,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
// Check for nontrivial bases (and recurse). // Check for nontrivial bases (and recurse).
for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) { for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) {
const RecordType *BaseRT = bi->getType()->getAs<RecordType>(); const RecordType *BaseRT = bi->getType()->getAs<RecordType>();
assert(BaseRT); assert(BaseRT && "Don't know how to handle dependent bases");
CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl()); CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl());
if (!(BaseRecTy->*hasTrivial)()) { if (!(BaseRecTy->*hasTrivial)()) {
SourceLocation BaseLoc = bi->getSourceRange().getBegin(); SourceLocation BaseLoc = bi->getSourceRange().getBegin();

View File

@ -1976,6 +1976,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// and // and
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
HasConstCopyAssignment && Base != ClassDecl->bases_end(); ++Base) { HasConstCopyAssignment && Base != ClassDecl->bases_end(); ++Base) {
assert(!Base->getType()->isDependentType() &&
"Cannot generate implicit members for class with dependent bases.");
const CXXRecordDecl *BaseClassDecl const CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
const CXXMethodDecl *MD = 0; const CXXMethodDecl *MD = 0;

View File

@ -3119,9 +3119,8 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
} }
} }
/// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers /// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers,
/// , if any, found in visible type conversion functions found in ArgExpr's /// if any, found in visible type conversion functions found in ArgExpr's type.
/// type.
static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
Qualifiers VRQuals; Qualifiers VRQuals;
const RecordType *TyRec; const RecordType *TyRec;
@ -3139,7 +3138,7 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl()); CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
OverloadedFunctionDecl *Conversions = OverloadedFunctionDecl *Conversions =
ClassDecl->getVisibleConversionFunctions(); ClassDecl->getVisibleConversionFunctions();
for (OverloadedFunctionDecl::function_iterator Func for (OverloadedFunctionDecl::function_iterator Func
= Conversions->function_begin(); = Conversions->function_begin();

View File

@ -695,7 +695,7 @@ DeduceTemplateArguments(ASTContext &Context,
CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl()); CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
for (CXXRecordDecl::base_class_iterator Base = Next->bases_begin(), for (CXXRecordDecl::base_class_iterator Base = Next->bases_begin(),
BaseEnd = Next->bases_end(); BaseEnd = Next->bases_end();
Base != BaseEnd; ++Base) { Base != BaseEnd; ++Base) {
assert(Base->getType()->isRecordType() && assert(Base->getType()->isRecordType() &&
"Base class that isn't a record?"); "Base class that isn't a record?");
ToVisit.push_back(Base->getType()->getAs<RecordType>()); ToVisit.push_back(Base->getType()->getAs<RecordType>());