[PATCH] D33324: [index] Avoid infinite recursion when looking up a dependent name
Alex Lorenz via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu May 18 10:13:50 PDT 2017
arphaman created this revision.
This is a regression introduced by r302632 .
Repository:
rL LLVM
https://reviews.llvm.org/D33324
Files:
include/clang/AST/CXXInheritance.h
lib/AST/CXXInheritance.cpp
test/Index/Core/index-dependent-source.cpp
Index: test/Index/Core/index-dependent-source.cpp
===================================================================
--- test/Index/Core/index-dependent-source.cpp
+++ 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: lib/AST/CXXInheritance.cpp
===================================================================
--- lib/AST/CXXInheritance.cpp
+++ 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())
+ BaseRecord = nullptr;
+ else if (VisitedDependentRecords.count(BaseRecord))
+ BaseRecord = nullptr;
+ else
+ VisitedDependentRecords.insert(BaseRecord);
+ }
} else {
BaseRecord = cast<CXXRecordDecl>(
BaseSpec.getType()->castAs<RecordType>()->getDecl());
Index: include/clang/AST/CXXInheritance.h
===================================================================
--- include/clang/AST/CXXInheritance.h
+++ 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33324.99456.patch
Type: text/x-patch
Size: 2760 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170518/b4fb4ed3/attachment.bin>
More information about the cfe-commits
mailing list