https://github.com/Purna-Chandra-4706 updated https://github.com/llvm/llvm-project/pull/219781
>From 9affe370ea05ee3af43a7efb65121cb60375b109 Mon Sep 17 00:00:00 2001 From: Purna-Chandra-4706 <[email protected]> Date: Sun, 30 Aug 2026 12:42:13 +0530 Subject: [PATCH 1/2] [clang-tidy] Fix crash and infinite loop on incomplete types clang-tidy crashes when a class inherits from a forward-declared base class. This happens because hasMemberName() is called on an incomplete type in readability-identifier-naming check. There's also an infinite loop in misc-multiple-inheritance check when there's circular inheritance (A inherits B, B inherits A). The isInterface() function keeps calling itself forever. Fixed by adding hasDefinition() checks before accessing base class members, and by inserting a provisional cache entry to break cycles. Added regression tests for both cases. Fixes #213948 --- .../clang-tidy/misc/MultipleInheritanceCheck.cpp | 7 +++++-- .../clang-tidy/readability/IdentifierNamingCheck.cpp | 2 +- .../misc/multiple-inheritance-incomplete-type.cpp | 7 +++++++ .../readability/identifier-naming-incomplete-type.cpp | 9 +++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance-incomplete-type.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-incomplete-type.cpp diff --git a/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp index 72e6aa6ac0b47..3f3f4a0086897 100644 --- a/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp @@ -26,13 +26,16 @@ bool MultipleInheritanceCheck::isInterface(const CXXBaseSpecifier &Base) { if (!Node) return true; - assert(Node->isCompleteDefinition()); + if (!Node->hasDefinition()) + return false; // 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 +50,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/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 50644bbf37bce..54cb140b12e80 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -1259,7 +1259,7 @@ StyleKind IdentifierNamingCheck::findStyleKind( // necessary even if it's not an override. e.g. CRTP. for (const CXXBaseSpecifier &Base : Decl->getParent()->bases()) if (const auto *RD = Base.getType()->getAsCXXRecordDecl(); - RD && RD->hasMemberName(Decl->getDeclName())) + RD && RD->hasDefinition() && RD->hasMemberName(Decl->getDeclName())) return SK_Invalid; if (Decl->isConstexpr() && NamingStyles[SK_ConstexprMethod]) diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance-incomplete-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance-incomplete-type.cpp new file mode 100644 index 0000000000000..debf6b04c2c4e --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance-incomplete-type.cpp @@ -0,0 +1,7 @@ +// RUN: %check_clang_tidy "%s" misc-multiple-inheritance "%t" + +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() {} }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-incomplete-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-incomplete-type.cpp new file mode 100644 index 0000000000000..5a516fe31f7b5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-incomplete-type.cpp @@ -0,0 +1,9 @@ +// RUN: %check_clang_tidy "%s" readability-identifier-naming "%t" + +template<class T> +struct X { + struct B; + struct A : public B { + virtual void foo() { } + }; +}; >From e3d9f370d00585faa51acd8d29f70d7c151f35ac Mon Sep 17 00:00:00 2001 From: Purna-Chandra-4706 <[email protected]> Date: Mon, 31 Aug 2026 16:51:55 +0530 Subject: [PATCH 2/2] Update Release Notes for #213948 --- clang-tools-extra/docs/ReleaseNotes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md index 420b7ddce20e6..1970fb62bfe8f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -164,6 +164,10 @@ infrastructure are described first, followed by tool-specific sections. - Fixed false positives when the pointee is written through a pointer assignment, such as `*(p = q) = 0`. +- Fixed an infinite loop in {doc}`misc-multiple-inheritance + <clang-tidy/checks/misc/multiple-inheritance>` check when resolving circular + inheritance. + - Improved {doc}`misc-redundant-expression <clang-tidy/checks/misc/redundant-expression>` by fixing false positives in nested expressions involving different macros or a mix of macro and @@ -200,6 +204,9 @@ infrastructure are described first, followed by tool-specific sections. - Improved {doc}`readability-identifier-naming <clang-tidy/checks/readability/identifier-naming>` check: + - Fixed a crash when checking a class that inherits from a forward-declared + base class. + - Fixed a crash when checking forward-declared classes with {option}`DefaultHungarianPrefix` enabled. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
