[index] Avoid one more crash caused by infinite recursion that happens when

looking up a dependent name in a record that derives from itself

rdar://32273000

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

llvm-svn: 303366
This commit is contained in:
Alex Lorenz 2017-05-18 18:06:07 +00:00
parent f8355ccb77
commit 6796c0b97f
3 changed files with 32 additions and 3 deletions

View File

@ -127,7 +127,11 @@ class CXXBasePaths {
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
/// VisitedDependentRecords - Records the dependent records that have been
/// already visited.
llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
/// ambiguous paths while it is looking for a path from a derived
/// type to a base type.

View File

@ -57,6 +57,7 @@ bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
void CXXBasePaths::clear() {
Paths.clear();
ClassSubobjects.clear();
VisitedDependentRecords.clear();
ScratchPath.clear();
DetectedVirtual = nullptr;
}
@ -67,6 +68,7 @@ void CXXBasePaths::swap(CXXBasePaths &Other) {
std::swap(Origin, Other.Origin);
Paths.swap(Other.Paths);
ClassSubobjects.swap(Other.ClassSubobjects);
VisitedDependentRecords.swap(Other.VisitedDependentRecords);
std::swap(FindAmbiguities, Other.FindAmbiguities);
std::swap(RecordPaths, Other.RecordPaths);
std::swap(DetectVirtual, Other.DetectVirtual);
@ -278,8 +280,14 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
BaseRecord = TD->getTemplatedDecl();
}
if (BaseRecord && !BaseRecord->hasDefinition())
BaseRecord = nullptr;
if (BaseRecord) {
if (!BaseRecord->hasDefinition() ||
VisitedDependentRecords.count(BaseRecord)) {
BaseRecord = nullptr;
} else {
VisitedDependentRecords.insert(BaseRecord);
}
}
} else {
BaseRecord = cast<CXXRecordDecl>(
BaseSpec.getType()->castAs<RecordType>()->getDecl());

View File

@ -141,3 +141,20 @@ void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {
x.lookup;
typename UserOfUndefinedTemplateClass<T>::Type y;
}
template<typename T> struct Dropper;
template<typename T> struct Trait;
template<typename T>
struct Recurse : Trait<typename Dropper<T>::Type> { };
template<typename T>
struct Trait : Recurse<T> {
};
template<typename T>
void infiniteTraitRecursion(Trait<T> &t) {
// Shouldn't crash!
t.lookup;
}