https://github.com/qzhhhi created https://github.com/llvm/llvm-project/pull/204913
Prevent `readability-identifier-naming` from recursing indefinitely in dependent base lookup when `AggressiveDependentMemberLookup` maps a dependent template base back to the same record definition. Track visited `CXXRecordDecl` definitions while walking base classes and stop revisiting the same definition. Add a regression test covering the dependent base cycle reproducer. >From 729724741c21af552cc7a358d65ae0a1702ac740 Mon Sep 17 00:00:00 2001 From: qzhhhi <[email protected]> Date: Sat, 20 Jun 2026 05:39:33 +0000 Subject: [PATCH] [clang-tidy] Guard `readability-identifier-naming` recursion in dependent base lookup Prevent `readability-identifier-naming` from recursing indefinitely in dependent base lookup when `AggressiveDependentMemberLookup` maps a dependent template base back to the same record definition. Track visited `CXXRecordDecl` definitions while walking base classes and stop revisiting the same definition. Add a regression test covering the dependent base cycle reproducer. --- .../utils/RenamerClangTidyCheck.cpp | 21 +++++++++++++++---- ...identifier-naming-dependent-base-cycle.cpp | 17 +++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-dependent-base-cycle.cpp diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index cb7ef19827675..d55c8f2e05c71 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -17,6 +17,8 @@ #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SmallPtrSet.h" #include <optional> #define DEBUG_TYPE "clang-tidy" @@ -118,6 +120,8 @@ static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) { return ND; } +using RecursionProtectionSet = llvm::SmallPtrSet<const CXXRecordDecl *, 4>; + /// Returns a decl matching the \p DeclName in \p Parent or one of its base /// classes. If \p AggressiveTemplateLookup is `true` then it will check /// template dependent base classes as well. @@ -125,9 +129,17 @@ static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) { /// flag indicating the multiple resolutions. static NameLookup findDeclInBases(const CXXRecordDecl &Parent, StringRef DeclName, - bool AggressiveTemplateLookup) { + bool AggressiveTemplateLookup, + RecursionProtectionSet &Visited) { if (!Parent.hasDefinition()) return NameLookup(nullptr); + + const auto *Definition = Parent.getDefinition(); + if (!Visited.insert(Definition).second) + return NameLookup(nullptr); + auto RemoveFromVisited = + llvm::scope_exit([&Visited, Definition] { Visited.erase(Definition); }); + if (const NamedDecl *InClassRef = findDecl(Parent, DeclName)) return NameLookup(InClassRef); const NamedDecl *Found = nullptr; @@ -144,8 +156,8 @@ static NameLookup findDeclInBases(const CXXRecordDecl &Parent, } if (!Record) continue; - if (auto Search = - findDeclInBases(*Record, DeclName, AggressiveTemplateLookup)) { + if (auto Search = findDeclInBases(*Record, DeclName, + AggressiveTemplateLookup, Visited)) { if (*Search) { if (Found) return NameLookup( @@ -301,8 +313,9 @@ class RenamerClangTidyVisitor return true; const StringRef DependentName = DeclName.getAsIdentifierInfo()->getName(); + RecursionProtectionSet Visited; if (const NameLookup Resolved = findDeclInBases( - *Base, DependentName, AggressiveDependentMemberLookup)) { + *Base, DependentName, AggressiveDependentMemberLookup, Visited)) { if (*Resolved) Check->addUsage(*Resolved, DepMemberRef->getMemberNameInfo().getSourceRange(), SM); diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-dependent-base-cycle.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-dependent-base-cycle.cpp new file mode 100644 index 0000000000000..9dd966f92edf3 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-dependent-base-cycle.cpp @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-identifier-naming.AggressiveDependentMemberLookup: true \ +// RUN: }}' -- -fno-delayed-template-parsing + +template <class T> +struct A; + +template <class T> +struct A<const T> { + int x; +}; + +template <class T> +struct A : A<const T> { + A() { this->x; } +}; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
