Author: Purna Chandra
Date: 2026-09-22T21:54:11+08:00
New Revision: db17738290efb586b9700bbecef3a82084a9c5f4

URL: 
https://github.com/llvm/llvm-project/commit/db17738290efb586b9700bbecef3a82084a9c5f4
DIFF: 
https://github.com/llvm/llvm-project/commit/db17738290efb586b9700bbecef3a82084a9c5f4.diff

LOG: [clang-tidy] Fix infinite loop in misc-multiple-inheritance (#220223)

This PR contains the fix for the infinite loop in
`misc-multiple-inheritance`. The checker was getting stuck in an
infinite cycle when it encountered circular inheritance. I fixed this by
adding a visited map (`InterfaceMap.try_emplace(Node, false)`) to break
the cycle during the DFS traversal.

Part of #213948.

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
    clang-tools-extra/docs/ReleaseNotes.md
    clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
index 72e6aa6ac0b47..633842f3f6b22 100644
--- a/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
@@ -23,16 +23,16 @@ AST_MATCHER(CXXRecordDecl, hasBases) {
 
 bool MultipleInheritanceCheck::isInterface(const CXXBaseSpecifier &Base) {
   const CXXRecordDecl *const Node = Base.getType()->getAsCXXRecordDecl();
-  if (!Node)
+  if (!Node || !Node->hasDefinition())
     return true;
 
-  assert(Node->isCompleteDefinition());
-
   // Short circuit the lookup if we have analyzed this record before.
   if (const auto CachedValue = InterfaceMap.find(Node);
       CachedValue != InterfaceMap.end())
     return CachedValue->second;
 
+  InterfaceMap.try_emplace(Node, false);
+
   // To be an interface, a class must have...
   const bool CurrentClassIsInterface =
       // ...no bases that aren't interfaces...
@@ -47,7 +47,7 @@ bool MultipleInheritanceCheck::isInterface(const 
CXXBaseSpecifier &Base) {
         return M->isUserProvided() && !M->isPureVirtual() && !M->isStatic();
       });
 
-  InterfaceMap.try_emplace(Node, CurrentClassIsInterface);
+  InterfaceMap[Node] = CurrentClassIsInterface;
   return CurrentClassIsInterface;
 }
 

diff  --git a/clang-tools-extra/docs/ReleaseNotes.md 
b/clang-tools-extra/docs/ReleaseNotes.md
index 0441aef375c54..4973bef42e3bf 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -212,6 +212,10 @@ infrastructure are described first, followed by 
tool-specific sections.
 
   - No longer diagnoses variables declared with `decltype(auto)`, where the
     suggested `const` does not compile.
+    
+- Fixed an infinite loop in {doc}`misc-multiple-inheritance
+  <clang-tidy/checks/misc/multiple-inheritance>` when checking a class that
+  inherits from itself or has a circular inheritance graph.
 
 - Improved {doc}`misc-redundant-expression
   <clang-tidy/checks/misc/redundant-expression>` by fixing false positives in

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
index 257e16ab18f2f..15aa5d4d11228 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
@@ -182,3 +182,9 @@ struct VI : virtual VA { virtual void h() = 0; };
 struct VD : VI, VB {};
 
 } // namespace M
+
+template<class T> struct X {
+  struct B;
+  struct A : public B { virtual void foo() {} };
+};
+template<class T> struct X<T>::B : public A { virtual void foo() {} };


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to