https://github.com/irishrover updated https://github.com/llvm/llvm-project/pull/183921
>From 5d517060b6dc37b1568b5af332e763b81ad35eba Mon Sep 17 00:00:00 2001 From: Zinovy Nis <[email protected]> Date: Sat, 28 Feb 2026 17:33:50 +0300 Subject: [PATCH 1/2] [clang-tidy] Skip overloaded functions in modernize-use-string-view --- .../modernize/UseStringViewCheck.cpp | 24 +++++++++++++++++++ .../checkers/modernize/use-string-view.cpp | 7 ++++++ 2 files changed, 31 insertions(+) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp index 1dc4cc9856549..f03c9c008389a 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp @@ -21,6 +21,29 @@ using namespace clang::ast_matchers; namespace clang::tidy::modernize { +namespace { +AST_MATCHER(FunctionDecl, isOverloaded) { + const DeclarationName Name = Node.getDeclName(); + // Skip lambda-like functions + if (Name.isEmpty()) + return false; + const DeclContext *DC = Node.getDeclContext(); + auto LookupResult = DC->lookup(Name); + size_t UniqueSignatures = 0; + llvm::SmallPtrSet<const FunctionDecl *, 2> SeenFunctions; + for (NamedDecl *ND : LookupResult) { + if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { + if (SeenFunctions.insert(FD->getCanonicalDecl()).second) { + UniqueSignatures++; + if (UniqueSignatures > 1) + return true; + } + } + } + return false; +} +} // namespace + static constexpr StringRef StringViewClassKey = "string"; static constexpr StringRef WStringViewClassKey = "wstring"; static constexpr StringRef U8StringViewClassKey = "u8string"; @@ -81,6 +104,7 @@ void UseStringViewCheck::registerMatchers(MatchFinder *Finder) { functionDecl( isDefinition(), unless(anyOf(VirtualOrOperator, IgnoredFunctionsMatcher, + isOverloaded(), ast_matchers::isExplicitTemplateSpecialization())), returns(IsStdString), hasDescendant(returnStmt()), unless(hasDescendant(returnStmt(hasReturnValue(unless( diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp index 2a00a7200ee76..832af0c26ef70 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp @@ -365,6 +365,13 @@ std::string lambda() { }(); } +namespace overloads { +std::string dbl2str(double f); +std::string overload(int) { return "int"; } +std::string overload(double f) { return "f=" + dbl2str(f); } +std::string overload(std::string) { return "string"; } +} + struct TemplateString { static constexpr char* val = "TEMPLATE"; template<typename T> >From 10abeb1ad0a0dbf238bf4c86cca2e95ffda0a3d0 Mon Sep 17 00:00:00 2001 From: Zinovy Nis <[email protected]> Date: Thu, 5 Mar 2026 21:38:56 +0300 Subject: [PATCH 2/2] Extend the tests --- .../modernize/UseStringViewCheck.cpp | 15 ++++++- .../checkers/modernize/use-string-view.cpp | 42 ++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp index f03c9c008389a..638b02c175576 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStringViewCheck.cpp @@ -24,7 +24,7 @@ namespace clang::tidy::modernize { namespace { AST_MATCHER(FunctionDecl, isOverloaded) { const DeclarationName Name = Node.getDeclName(); - // Skip lambda-like functions + // Sanity check if (Name.isEmpty()) return false; const DeclContext *DC = Node.getDeclContext(); @@ -32,7 +32,18 @@ AST_MATCHER(FunctionDecl, isOverloaded) { size_t UniqueSignatures = 0; llvm::SmallPtrSet<const FunctionDecl *, 2> SeenFunctions; for (NamedDecl *ND : LookupResult) { - if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { + const FunctionDecl *FD = nullptr; + if (const auto *Func = dyn_cast<FunctionDecl>(ND)) { + // Regular functions + FD = Func; + } else if (const auto *USD = dyn_cast<UsingShadowDecl>(ND)) { + // Overloads via "using ns::func_name" + FD = dyn_cast<FunctionDecl>(USD->getTargetDecl()); + } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND)) { + // Templated functions + FD = FTD->getTemplatedDecl(); + } + if (FD) { if (SeenFunctions.insert(FD->getCanonicalDecl()).second) { UniqueSignatures++; if (UniqueSignatures > 1) diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp index 832af0c26ef70..5174d2111b062 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-string-view.cpp @@ -211,6 +211,14 @@ MyString<wchar_t> aliasedWChar() { return L"aliasedWChar"; } +namespace overload_funcs_redeclared { + std::basic_string<char> overload(int); + std::string overload(int); + std::string overload(int) { return "int"; } +// CHECK-MESSAGES:[[@LINE-1]]:3: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view] +// CHECK-FIXES: std::string_view overload(int) { return "int"; } +} + // ========================================================== // Negative tests // ========================================================== @@ -365,13 +373,45 @@ std::string lambda() { }(); } -namespace overloads { +namespace overload_funcs { std::string dbl2str(double f); +// Skip overloaded functions std::string overload(int) { return "int"; } +// Because of this overload (non-literal return) the fix should not be applied std::string overload(double f) { return "f=" + dbl2str(f); } std::string overload(std::string) { return "string"; } } +namespace overload_methods { +struct Foo { + // Skip overloaded methods + std::string overload(int) { return "int"; } + std::string overload(double f) { return "double"; } + std::string overload(std::string) { return "string"; } +}; +} + +namespace overload_methods_nested_classes { +struct Bar { + std::string overload(int) { return "int"; } + std::string overload(std::string) { return "string"; } + + struct FooBar { + std::string overload(char*) { return "char*"; } + std::string overload(double f) { return "double"; } + }; +}; +} + +namespace overload_methods_nested_namespaces { +namespace foo { + std::string overload(int) { return "int"; } + std::string overload(std::string) { return "string"; } +} +using foo::overload; +std::string overload(char*) { return "char*"; } +} + struct TemplateString { static constexpr char* val = "TEMPLATE"; template<typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
