From: Sebastian Redl Date: Sun, 25 Oct 2009 17:03:50 +0000 (+0000) Subject: Audit the code for places where it is assumed that every base specifier refers to... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9994a34f6cf842721ba7723edc0b9036229fe387;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85055 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 457f4c85a0..2e3bbce9e4 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -364,34 +364,36 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD, } } } - + if (getNumBases() == 0 && getNumVBases() == 0) return; - + llvm::SmallPtrSet ConversionFunctions; if (!inTopClass) collectConversionFunctions(ConversionFunctions); - + for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(), E = vbases_end(); VBase != E; ++VBase) { - CXXRecordDecl *VBaseClassDecl - = cast(VBase->getType()->getAs()->getDecl()); - VBaseClassDecl->getNestedVisibleConversionFunctions(RD, - TopConversionsTypeSet, - (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); - + if (const RecordType *RT = VBase->getType()->getAs()) { + CXXRecordDecl *VBaseClassDecl + = cast(RT->getDecl()); + VBaseClassDecl->getNestedVisibleConversionFunctions(RD, + TopConversionsTypeSet, + (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); + } } for (CXXRecordDecl::base_class_iterator Base = bases_begin(), E = bases_end(); Base != E; ++Base) { if (Base->isVirtual()) continue; - CXXRecordDecl *BaseClassDecl - = cast(Base->getType()->getAs()->getDecl()); - - BaseClassDecl->getNestedVisibleConversionFunctions(RD, - TopConversionsTypeSet, - (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); - + if (const RecordType *RT = Base->getType()->getAs()) { + CXXRecordDecl *BaseClassDecl + = cast(RT->getDecl()); + + BaseClassDecl->getNestedVisibleConversionFunctions(RD, + TopConversionsTypeSet, + (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); + } } } diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index c79cc3c1db..0b159c3a7b 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -47,6 +47,8 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { if (!i->isVirtual()) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); // 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. for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); @@ -97,6 +101,8 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD, const CXXRecordDecl *&FirstPrimary) { for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); if (!i->isVirtual()) { @@ -123,6 +129,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { // indirect bases, and record all their primary virtual base classes. for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); IdentifyPrimaryBases(Base); @@ -173,6 +181,8 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, llvm::SmallSet &IndirectPrimary) { for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); #if 0 @@ -235,6 +245,8 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, // Check bases. for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { + assert(!I->getType()->isDependentType() && + "Cannot layout class with dependent bases."); if (I->isVirtual()) continue; @@ -305,6 +317,8 @@ void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD, // Update bases. for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { + assert(!I->getType()->isDependentType() && + "Cannot layout class with dependent bases."); if (I->isVirtual()) continue; diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index 446678ab6d..9a30f59465 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -452,6 +452,8 @@ class RecordLayoutDumper : public ASTConsumer { // Dump (non-virtual) bases for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { + assert(!I->getType()->isDependentType() && + "Cannot layout class with dependent bases."); if (I->isVirtual()) continue; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1b4c594aae..fe8052981f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5034,7 +5034,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { // Check for nontrivial bases (and recurse). for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) { const RecordType *BaseRT = bi->getType()->getAs(); - assert(BaseRT); + assert(BaseRT && "Don't know how to handle dependent bases"); CXXRecordDecl *BaseRecTy = cast(BaseRT->getDecl()); if (!(BaseRecTy->*hasTrivial)()) { SourceLocation BaseLoc = bi->getSourceRange().getBegin(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6d1f4ea4a8..21f9e84728 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1976,6 +1976,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // and for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); HasConstCopyAssignment && Base != ClassDecl->bases_end(); ++Base) { + assert(!Base->getType()->isDependentType() && + "Cannot generate implicit members for class with dependent bases."); const CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); const CXXMethodDecl *MD = 0; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index fbb50aea87..40e1450414 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3119,9 +3119,8 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S, } } -/// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers -/// , if any, found in visible type conversion functions found in ArgExpr's -/// type. +/// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers, +/// if any, found in visible type conversion functions found in ArgExpr's type. static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { Qualifiers VRQuals; const RecordType *TyRec; @@ -3139,7 +3138,7 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); OverloadedFunctionDecl *Conversions = - ClassDecl->getVisibleConversionFunctions(); + ClassDecl->getVisibleConversionFunctions(); for (OverloadedFunctionDecl::function_iterator Func = Conversions->function_begin(); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 32ae0a8dd0..a7ca8e874e 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -695,7 +695,7 @@ DeduceTemplateArguments(ASTContext &Context, CXXRecordDecl *Next = cast(NextT->getDecl()); for (CXXRecordDecl::base_class_iterator Base = Next->bases_begin(), BaseEnd = Next->bases_end(); - Base != BaseEnd; ++Base) { + Base != BaseEnd; ++Base) { assert(Base->getType()->isRecordType() && "Base class that isn't a record?"); ToVisit.push_back(Base->getType()->getAs());