This revision was automatically updated to reflect the committed changes. arphaman marked an inline comment as done. Closed by commit rL303366: [index] Avoid one more crash caused by infinite recursion that happens when (authored by arphaman).
Changed prior to commit: https://reviews.llvm.org/D33324?vs=99456&id=99466#toc Repository: rL LLVM https://reviews.llvm.org/D33324 Files: cfe/trunk/include/clang/AST/CXXInheritance.h cfe/trunk/lib/AST/CXXInheritance.cpp cfe/trunk/test/Index/Core/index-dependent-source.cpp Index: cfe/trunk/include/clang/AST/CXXInheritance.h =================================================================== --- cfe/trunk/include/clang/AST/CXXInheritance.h +++ cfe/trunk/include/clang/AST/CXXInheritance.h @@ -127,7 +127,11 @@ /// 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. Index: cfe/trunk/test/Index/Core/index-dependent-source.cpp =================================================================== --- cfe/trunk/test/Index/Core/index-dependent-source.cpp +++ cfe/trunk/test/Index/Core/index-dependent-source.cpp @@ -141,3 +141,20 @@ 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; +} Index: cfe/trunk/lib/AST/CXXInheritance.cpp =================================================================== --- cfe/trunk/lib/AST/CXXInheritance.cpp +++ cfe/trunk/lib/AST/CXXInheritance.cpp @@ -57,6 +57,7 @@ void CXXBasePaths::clear() { Paths.clear(); ClassSubobjects.clear(); + VisitedDependentRecords.clear(); ScratchPath.clear(); DetectedVirtual = nullptr; } @@ -67,6 +68,7 @@ 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 @@ 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());
Index: cfe/trunk/include/clang/AST/CXXInheritance.h =================================================================== --- cfe/trunk/include/clang/AST/CXXInheritance.h +++ cfe/trunk/include/clang/AST/CXXInheritance.h @@ -127,7 +127,11 @@ /// 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. Index: cfe/trunk/test/Index/Core/index-dependent-source.cpp =================================================================== --- cfe/trunk/test/Index/Core/index-dependent-source.cpp +++ cfe/trunk/test/Index/Core/index-dependent-source.cpp @@ -141,3 +141,20 @@ 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; +} Index: cfe/trunk/lib/AST/CXXInheritance.cpp =================================================================== --- cfe/trunk/lib/AST/CXXInheritance.cpp +++ cfe/trunk/lib/AST/CXXInheritance.cpp @@ -57,6 +57,7 @@ void CXXBasePaths::clear() { Paths.clear(); ClassSubobjects.clear(); + VisitedDependentRecords.clear(); ScratchPath.clear(); DetectedVirtual = nullptr; } @@ -67,6 +68,7 @@ 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 @@ 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());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits