]> granicus.if.org Git - clang/commitdiff
[index] Avoid one more crash caused by infinite recursion that happens when
authorAlex Lorenz <arphaman@gmail.com>
Thu, 18 May 2017 18:06:07 +0000 (18:06 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Thu, 18 May 2017 18:06:07 +0000 (18:06 +0000)
looking up a dependent name in a record that derives from itself

rdar://32273000

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303366 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/CXXInheritance.h
lib/AST/CXXInheritance.cpp
test/Index/Core/index-dependent-source.cpp

index a7961ebe8ce6ad89003f5f99f917c55ec39e72a0..980608570fd68044d2f876d0a95f6761056ab12c 100644 (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.
index 746602d47be52683d43c70fb4e1761395c20bf64..fc4d8b137337f38ff08798052be8f73968c8fe62 100644 (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());
index 8c097b935a37ca686346caa0f59f7c561bba1f9f..59c6286cd3dd9e9ce66249878c9d0dfee5a18f6b 100644 (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;
+}