forked from OSchip/llvm-project
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:
parent
c45c03c9dd
commit
1054faed32
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>());
|
||||||
|
|
Loading…
Reference in New Issue