forked from OSchip/llvm-project
[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:
parent
f8355ccb77
commit
6796c0b97f
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue