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 457f4c8..2e3bbce 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -364,34 +364,36 @@
}
}
}
-
+
if (getNumBases() == 0 && getNumVBases() == 0)
return;
-
+
llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions;
if (!inTopClass)
collectConversionFunctions(ConversionFunctions);
-
+
for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(),
E = vbases_end(); VBase != E; ++VBase) {
- CXXRecordDecl *VBaseClassDecl
- = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
- TopConversionsTypeSet,
- (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
-
+ if (const RecordType *RT = VBase->getType()->getAs<RecordType>()) {
+ CXXRecordDecl *VBaseClassDecl
+ = cast<CXXRecordDecl>(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<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-
- BaseClassDecl->getNestedVisibleConversionFunctions(RD,
- TopConversionsTypeSet,
- (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
-
+ if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(RT->getDecl());
+
+ BaseClassDecl->getNestedVisibleConversionFunctions(RD,
+ TopConversionsTypeSet,
+ (inTopClass ? TopConversionsTypeSet : ConversionFunctions));
+ }
}
}
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index c79cc3c..0b159c3 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -47,6 +47,8 @@
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<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first.
@@ -82,6 +84,8 @@
// 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<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
@@ -97,6 +101,8 @@
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<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (!i->isVirtual()) {
@@ -123,6 +129,8 @@
// 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<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
IdentifyPrimaryBases(Base);
@@ -173,6 +181,8 @@
llvm::SmallSet<const CXXRecordDecl*, 32> &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<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
#if 0
@@ -235,6 +245,8 @@
// 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 @@
// 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 446678a..9a30f59 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -452,6 +452,8 @@
// 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 1b4c594..fe80529 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5034,7 +5034,7 @@
// 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<RecordType>();
- assert(BaseRT);
+ assert(BaseRT && "Don't know how to handle dependent bases");
CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl());
if (!(BaseRecTy->*hasTrivial)()) {
SourceLocation BaseLoc = bi->getSourceRange().getBegin();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6d1f4ea..21f9e84 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1976,6 +1976,8 @@
// 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<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
const CXXMethodDecl *MD = 0;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fbb50ae..40e1450 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3119,9 +3119,8 @@
}
}
-/// 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 @@
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(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 32ae0a8..a7ca8e8 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -695,7 +695,7 @@
CXXRecordDecl *Next = cast<CXXRecordDecl>(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<RecordType>());