[clang-tools-extra] db17738 - [clang-tidy] Fix infinite loop in misc-multiple-inheritance (#220223)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 22 06:54:18 PDT 2026
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() {} };
More information about the cfe-commits
mailing list