https://github.com/irishrover updated 
https://github.com/llvm/llvm-project/pull/174288

>From 58d287674258fbafede18cfd0d82f0758fb46d51 Mon Sep 17 00:00:00 2001
From: Zinovy Nis <[email protected]>
Date: Sat, 3 Jan 2026 17:48:40 +0300
Subject: [PATCH 1/3] [clang-tidy] Add a new check
 'performance-string-view-conversions'

Looks for redundant conversions from ``std::[w|u8|u16|u32]string_view`` to
``std::[...]string`` in call expressions expecting ``std::[...]string_view``.
And fixes them.
---
 .../clang-tidy/performance/CMakeLists.txt     |   1 +
 .../performance/PerformanceTidyModule.cpp     |   3 +
 .../StringViewConversionsCheck.cpp            | 144 ++++++++++++++++++
 .../performance/StringViewConversionsCheck.h  |  34 +++++
 clang-tools-extra/docs/ReleaseNotes.rst       |  19 ++-
 .../docs/clang-tidy/checks/list.rst           |   1 +
 .../performance/string-view-conversions.rst   |  34 +++++
 .../clang-tidy/checkers/Inputs/Headers/string |  24 +++
 .../performance/string-view-conversions.cpp   |  92 +++++++++++
 9 files changed, 346 insertions(+), 6 deletions(-)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions.cpp

diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 9a2f90069edbf..4dba117e1ee54 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_library(clangTidyPerformanceModule STATIC
   NoexceptMoveConstructorCheck.cpp
   NoexceptSwapCheck.cpp
   PerformanceTidyModule.cpp
+  StringViewConversionsCheck.cpp
   TriviallyDestructibleCheck.cpp
   TypePromotionInMathFnCheck.cpp
   UnnecessaryCopyInitializationCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp 
b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
index 6bab1a46d18db..294a209e4c602 100644
--- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -23,6 +23,7 @@
 #include "NoexceptDestructorCheck.h"
 #include "NoexceptMoveConstructorCheck.h"
 #include "NoexceptSwapCheck.h"
+#include "StringViewConversionsCheck.h"
 #include "TriviallyDestructibleCheck.h"
 #include "TypePromotionInMathFnCheck.h"
 #include "UnnecessaryCopyInitializationCheck.h"
@@ -62,6 +63,8 @@ class PerformanceModule : public ClangTidyModule {
         "performance-noexcept-move-constructor");
     CheckFactories.registerCheck<NoexceptSwapCheck>(
         "performance-noexcept-swap");
+    CheckFactories.registerCheck<StringViewConversionsCheck>(
+        "performance-string-view-conversions");
     CheckFactories.registerCheck<TriviallyDestructibleCheck>(
         "performance-trivially-destructible");
     CheckFactories.registerCheck<TypePromotionInMathFnCheck>(
diff --git 
a/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
new file mode 100644
index 0000000000000..bb11f81c7034e
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
@@ -0,0 +1,144 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "StringViewConversionsCheck.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+static auto getStringTypeMatcher(StringRef CharType) {
+  return hasCanonicalType(hasDeclaration(cxxRecordDecl(hasName(CharType))));
+}
+
+void StringViewConversionsCheck::registerMatchers(MatchFinder *Finder) {
+  // Matchers for std::basic_string[_view] families
+  // (includes std::string, std::wstring, std::u8string, etc.)
+  const auto IsStdString = getStringTypeMatcher("::std::basic_string");
+  const auto IsStdStringView = 
getStringTypeMatcher("::std::basic_string_view");
+
+  // Matches pointer to any character type (char*, const char*, wchar_t*, etc.)
+  // or array of any character type (char[], char[N], etc.)
+  const auto IsCharPointerOrArray =
+      anyOf(hasType(pointerType(pointee(isAnyCharacter()))),
+            hasType(arrayType(hasElementType(isAnyCharacter()))));
+
+  // Matches expressions that can be implicitly converted to string_view:
+  // - string_view itself
+  // - string literals ("hello", L"hello", u8"hello", etc.)
+  // - character pointers (const char*, char*)
+  // - character arrays (char[], char[N])
+  const auto ImplicitlyConvertibleToStringView =
+      expr(anyOf(hasType(IsStdStringView), stringLiteral(),
+                 IsCharPointerOrArray))
+          .bind("originalStringView");
+
+  // Matches std::string construction from an expression that is
+  // implicitly convertible to string_view.
+  // Excludes copy and move constructors to avoid false positives.
+  const auto RedundantStringConstruction = cxxConstructExpr(
+      hasType(IsStdString),
+      hasArgument(0, ignoringImplicit(ImplicitlyConvertibleToStringView)),
+      unless(hasDeclaration(cxxConstructorDecl(isCopyConstructor()))),
+      unless(hasDeclaration(cxxConstructorDecl(isMoveConstructor()))));
+
+  // Matches functional cast syntax: std::string(expr)
+  // This produces CXXFunctionalCastExpr in the AST.
+  const auto RedundantFunctionalCast =
+      cxxFunctionalCastExpr(hasType(IsStdString),
+                            hasDescendant(RedundantStringConstruction))
+          .bind("redundantExpr");
+
+  // Matches brace initialization syntax: std::string{expr}
+  // This produces CXXTemporaryObjectExpr in the AST.
+  const auto RedundantTemporaryObject =
+      cxxTemporaryObjectExpr(
+          hasType(IsStdString),
+          hasArgument(0, ignoringImplicit(ImplicitlyConvertibleToStringView)),
+          unless(hasDeclaration(cxxConstructorDecl(isCopyConstructor()))),
+          unless(hasDeclaration(cxxConstructorDecl(isMoveConstructor()))))
+          .bind("redundantExpr");
+
+  // Main matcher: finds function calls where an argument:
+  // 1. Has type string_view (after implicit conversions)
+  // 2. Contains a redundant std::string construction (either syntax)
+  // 3. Does NOT contain operator+ (which requires std::string operands,
+  //    so the conversion would not be redundant in that case)
+  //
+  // Example patterns detected:
+  //   foo(std::string(sv))     - string_view -> string -> string_view
+  //   foo(std::string{"lit"})  - literal -> string -> string_view
+  //
+  // Example patterns excluded:
+  //   foo(std::string(sv) + "bar")  - operator+ needs std::string
+  Finder->addMatcher(
+      callExpr(
+          forEachArgumentWithParam(
+              expr(hasType(IsStdStringView),
+                   hasDescendant(expr(anyOf(RedundantFunctionalCast,
+                                            RedundantTemporaryObject))),
+                   // Exclude cases where std::string is used with operator+
+                   // since string_view doesn't support concatenation.
+                   unless(hasDescendant(cxxOperatorCallExpr(
+                       hasOverloadedOperatorName("+"), hasType(IsStdString)))))
+                  .bind("expr"),
+              parmVarDecl(hasType(IsStdStringView))))
+          .bind("call"),
+      this);
+}
+
+void StringViewConversionsCheck::check(const MatchFinder::MatchResult &Result) 
{
+  // Get the full argument expression passed to the function.
+  // This has type string_view after implicit conversions.
+  const auto *ParamExpr = Result.Nodes.getNodeAs<Expr>("expr");
+  if (!ParamExpr)
+    return;
+
+  // Get the redundant std::string construction expression.
+  // This is either CXXFunctionalCastExpr for std::string(x) syntax
+  // or CXXTemporaryObjectExpr for std::string{x} syntax.
+  const auto *RedundantExpr = Result.Nodes.getNodeAs<Expr>("redundantExpr");
+  if (!RedundantExpr)
+    return;
+
+  // Get the original expression that was passed to std::string constructor.
+  // This is what we want to use as the replacement.
+  const auto *OriginalExpr = 
Result.Nodes.getNodeAs<Expr>("originalStringView");
+  if (!OriginalExpr)
+    return;
+
+  // Sanity check. Verify that the redundant expression is the direct source of
+  // the argument, not part of a larger expression (e.g., std::string(sv) +
+  // "bar"). If source ranges don't match, there's something between the string
+  // construction and the function argument, so we shouldn't transform.
+  if (ParamExpr->getSourceRange() != RedundantExpr->getSourceRange())
+    return;
+
+  // Extract the source text of the original expression to use as replacement.
+  // For example, if the code is std::string(sv), we extract "sv".
+  const StringRef OriginalText = Lexer::getSourceText(
+      CharSourceRange::getTokenRange(OriginalExpr->getSourceRange()),
+      *Result.SourceManager, getLangOpts());
+
+  // Skip if we couldn't extract the source text (e.g., macro expansion 
issues).
+  if (OriginalText.empty())
+    return;
+
+  diag(RedundantExpr->getBeginLoc(),
+       "redundant conversion to %0 and then back to %1")
+      << RedundantExpr->getType().getAsString()
+      << ParamExpr->getType().getAsString()
+      << FixItHint::CreateReplacement(
+             CharSourceRange::getTokenRange(RedundantExpr->getSourceRange()),
+             OriginalText);
+}
+
+} // namespace clang::tidy::performance
diff --git 
a/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.h 
b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.h
new file mode 100644
index 0000000000000..b2b013d5086b7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_STRINGVIEWCONVERSIONSCHECK_H
+#define 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_STRINGVIEWCONVERSIONSCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::performance {
+
+/// Looks for redundant conversions from std::string_view to std::string in
+/// call expressions expecting std::string_view. And fixes them.
+///
+/// For the user-facing documentation see:
+/// 
https://clang.llvm.org/extra/clang-tidy/checks/performance/string-view-conversions.html
+class StringViewConversionsCheck : public ClangTidyCheck {
+public:
+  StringViewConversionsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus17;
+  }
+};
+
+} // namespace clang::tidy::performance
+
+#endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_STRINGVIEWCONVERSIONSCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 391c3a6b3db79..9edd703326203 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -111,10 +111,10 @@ Hover
 Code completion
 ^^^^^^^^^^^^^^^
 
-- Added a new ``MacroFilter`` configuration option to ``Completion`` to 
-  allow fuzzy-matching with the ``FuzzyMatch`` option when suggesting 
-  macros. ``ExactPrefix`` is the default, which retains previous 
-  behavior of suggesting macros which match the prefix exactly.  
+- Added a new ``MacroFilter`` configuration option to ``Completion`` to
+  allow fuzzy-matching with the ``FuzzyMatch`` option when suggesting
+  macros. ``ExactPrefix`` is the default, which retains previous
+  behavior of suggesting macros which match the prefix exactly.
 
 Code actions
 ^^^^^^^^^^^^
@@ -205,7 +205,7 @@ Improvements to clang-tidy
 
 - Improved :program:`clang-tidy` by adding the `--removed-arg` option to remove
   arguments sent to the compiler when invoking Clang-Tidy. This option was also
-  added to :program:`run-clang-tidy.py` and :program:`clang-tidy-diff.py` and 
+  added to :program:`run-clang-tidy.py` and :program:`clang-tidy-diff.py` and
   can be configured in the config file through the `RemovedArgs` option.
 
 - Deprecated the :program:`clang-tidy` ``zircon`` module. All checks have been
@@ -265,6 +265,13 @@ New checks
   Finds virtual function overrides with different visibility than the function
   in the base class.
 
+- New :doc:`performance-string-view-conversions
+  <clang-tidy/checks/performance/string-view-conversions>` check.
+
+  Looks for redundant conversions from ``std::[w|u8|u16|u32]string_view`` to
+  ``std::[...]string`` in call expressions expecting ``std::[...]string_view``.
+  And fixes them.
+
 - New :doc:`readability-inconsistent-ifelse-braces
   <clang-tidy/checks/readability/inconsistent-ifelse-braces>` check.
 
@@ -364,7 +371,7 @@ New check aliases
   keeping initial check as an alias to the new one.
 
 - Renamed :doc:`google-build-namespaces 
<clang-tidy/checks/google/build-namespaces>` to
-  :doc:`misc-anonymous-namespace-in-header 
+  :doc:`misc-anonymous-namespace-in-header
   <clang-tidy/checks/misc/anonymous-namespace-in-header>`
   keeping initial check as an alias to the new one.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst 
b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index e0de2b9c2dada..d79566485b59f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -362,6 +362,7 @@ Clang-Tidy Checks
    :doc:`performance-noexcept-destructor <performance/noexcept-destructor>`, 
"Yes"
    :doc:`performance-noexcept-move-constructor 
<performance/noexcept-move-constructor>`, "Yes"
    :doc:`performance-noexcept-swap <performance/noexcept-swap>`, "Yes"
+   :doc:`performance-string-view-conversions 
<performance/string-view-conversions>`, "Yes"
    :doc:`performance-trivially-destructible 
<performance/trivially-destructible>`, "Yes"
    :doc:`performance-type-promotion-in-math-fn 
<performance/type-promotion-in-math-fn>`, "Yes"
    :doc:`performance-unnecessary-copy-initialization 
<performance/unnecessary-copy-initialization>`, "Yes"
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
new file mode 100644
index 0000000000000..c8a86b208044d
--- /dev/null
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - performance-string-view-conversions
+
+performance-string-view-conversions
+==========================================
+
+Looks for redundant conversions from ``std::[w|u8|u16|u32]string_view`` to
+``std::[...]string`` in call expressions expecting ``std::[...]string_view``.
+And fixes them.
+
+
+Before:
+
+
+.. code-block:: c++
+
+    void foo(int p1, std::string_view p2, double p3);
+    void bar(std::string_view sv) {
+        foo(42, std::string(sv), 3.14); // conversion to std::string is
+                                        // redundant as std::string_view
+                                        // is expected
+        foo(42, std::string("foo"), 3.14); // conversion to std::string is
+                                           // redundant as std::string_view
+                                           // is expected
+    }
+
+After:
+
+.. code-block:: c++
+
+    void foo(int p1, std::string_view p2, double p3);
+    void bar(std::string_view sv) {
+        foo(42, sv, 3.14);
+        foo(42, "foo", 3.14);
+    }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
index 6cedda4202f14..c3fd2cf6c1ff7 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
@@ -22,9 +22,11 @@ struct basic_string {
   typedef size_t size_type;
   typedef basic_string<C, T, A> _Type;
   basic_string();
+  basic_string(basic_string_view<C, T>);
   basic_string(const C *p, const A &a = A());
   basic_string(const C *p, size_type count);
   basic_string(const C *b, const C *e);
+  basic_string(size_t, C);
 
   ~basic_string();
 
@@ -90,8 +92,14 @@ struct basic_string {
 
 typedef basic_string<char> string;
 typedef basic_string<wchar_t> wstring;
+#if __cplusplus >= 202002L
+typedef basic_string<char8_t> u8string;
+typedef basic_string<char16_t> u16string;
+typedef basic_string<char32_t> u32string;
+#else
 typedef basic_string<char16> u16string;
 typedef basic_string<char32> u32string;
+#endif
 
 template <typename C, typename T>
 struct basic_string_view {
@@ -100,6 +108,7 @@ struct basic_string_view {
 
   const C *str;
   constexpr basic_string_view(const C* s) : str(s) {}
+  basic_string_view(const basic_string<C, T>&) {}
 
   const C *data() const;
 
@@ -136,8 +145,14 @@ struct basic_string_view {
 
 typedef basic_string_view<char> string_view;
 typedef basic_string_view<wchar_t> wstring_view;
+#if __cplusplus >= 202002L
+typedef basic_string_view<char8_t> u8string_view;
+typedef basic_string_view<char16_t> u16string_view;
+typedef basic_string_view<char32_t> u32string_view;
+#else
 typedef basic_string_view<char16> u16string_view;
 typedef basic_string_view<char32> u32string_view;
+#endif
 
 std::string operator+(const std::string&, const std::string&);
 std::string operator+(const std::string&, const char*);
@@ -166,6 +181,15 @@ bool operator!=(const char*, const std::string_view&);
 #endif
 
 size_t strlen(const char* str);
+
+namespace literals {
+namespace string_literals {
+  string operator""s(const char *, size_t);
+}
+namespace string_view_literals {
+  string_view operator""sv(const char *, size_t);
+}
+}
 }
 
 #endif // _STRING_
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions.cpp
new file mode 100644
index 0000000000000..72b7cf0ad4750
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++20 %s performance-string-view-conversions %t 
-- \
+// RUN:   -- -isystem %clang_tidy_headers
+
+#include <string>
+
+using namespace std::literals::string_literals;
+using namespace std::literals::string_view_literals;
+
+void foo_sv(int p1, std::string_view p2, double p3);
+void foo_wsv(int p1, std::wstring_view p2, double p3);
+void foo_u8sv(int p1, std::u8string_view p2, double p3);
+void foo_u16sv(int p1, std::u16string_view p2, double p3);
+void foo_u32sv(int p1, std::u32string_view p2, double p3);
+void foo_str(int p1, const std::string& p2, double p3);
+void foo_wstr(int p1, const std::wstring& p2, double p3);
+std::string foo_str(int p1);
+std::string_view foo_sv(int p1);
+
+void positive(std::string_view sv, std::wstring_view wsv) {
+  // string(string_view)
+  //
+  foo_sv(42, std::string(sv), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 
std::string and then back to std::string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_sv(42, sv, 3.14);
+
+  foo_sv(42, std::string("Hello, world"), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 
std::string and then back to std::string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_sv(42, "Hello, world", 3.14);
+
+  // TODO: support for ""sv literals
+  foo_sv(42, "Hello, world"s, 3.14);
+
+  foo_sv(42, std::string{"Hello, world"}, 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 
std::string and then back to std::string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_sv(42, "Hello, world", 3.14);
+
+  const char *ptr = "Hello, world";
+  foo_sv(42, std::string(ptr), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 
std::string and then back to std::string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_sv(42, ptr, 3.14);
+
+  char arr[] = "Hello, world";
+  foo_sv(42, std::string(arr), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 
std::string and then back to std::string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_sv(42, arr, 3.14);
+
+  // wstring(wstring_view)
+  //
+  foo_wsv(42, std::wstring(wsv), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant conversion to 
std::wstring and then back to std::wstring_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_wsv(42, wsv, 3.14);
+
+  const wchar_t *wptr = L"Hello, world";
+  foo_wsv(42, std::wstring(wptr), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant conversion to 
std::wstring and then back to std::wstring_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_wsv(42, wptr, 3.14);
+
+  // [u8|u16|32]string([u8|u16|32]string_view)
+  //
+  foo_u8sv(42, std::u8string(u8"Hello, world"), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant conversion to 
std::u8string and then back to std::u8string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_u8sv(42, u8"Hello, world", 3.14);
+
+  foo_u16sv(42, std::u16string(u"Hello, world"), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant conversion to 
std::u16string and then back to std::u16string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_u16sv(42, u"Hello, world", 3.14);
+
+  foo_u32sv(42, std::u32string(U"Hello, world"), 3.14);
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant conversion to 
std::u32string and then back to std::u32string_view 
[performance-string-view-conversions]
+  // CHECK-FIXES: foo_u32sv(42, U"Hello, world", 3.14);
+}
+
+void negative(std::string_view sv, std::wstring_view wsv) {
+  // No warnings expected: already string_view
+  foo_sv(42, sv, 3.14);
+  foo_sv(42, "Hello, world", 3.14);
+  // No warnings expected: complex expression
+  foo_sv(42, std::string(sv)  + "bar", 3.14);
+  foo_sv(42, "foo" + std::string(sv), 3.14);
+  foo_sv(42, std::string(sv) + std::string(sv), 3.14);
+  foo_sv(42, std::string("foo") + std::string("bar"), 3.14);
+  foo_sv(42, std::string(5, 'a'), 3.14);
+
+  // No warnings expected: string parameter, not string-view
+  foo_str(42, std::string(sv), 3.14);
+  foo_str(42, std::string("Hello, world"), 3.14);
+  foo_wstr(42, std::wstring(wsv), 3.14);
+  foo_wstr(42, std::wstring(L"Hello, world"), 3.14);
+
+  foo_sv(42, foo_str(42), 3.14);
+  foo_sv(42, foo_sv(42), 3.14);
+}

>From 50f287925999428836f0fb5c0a4b71d003cf67b6 Mon Sep 17 00:00:00 2001
From: Zinovy Nis <[email protected]>
Date: Tue, 6 Jan 2026 22:13:18 +0300
Subject: [PATCH 2/3] Update
 
clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst

Co-authored-by: EugeneZelenko <[email protected]>
---
 .../clang-tidy/checks/performance/string-view-conversions.rst   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
index c8a86b208044d..74708c9e6a353 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
@@ -1,7 +1,7 @@
 .. title:: clang-tidy - performance-string-view-conversions
 
 performance-string-view-conversions
-==========================================
+===================================
 
 Looks for redundant conversions from ``std::[w|u8|u16|u32]string_view`` to
 ``std::[...]string`` in call expressions expecting ``std::[...]string_view``.

>From 7fe10dcada581c856204bf26e156ca55604198ba Mon Sep 17 00:00:00 2001
From: Zinovy Nis <[email protected]>
Date: Tue, 6 Jan 2026 22:14:05 +0300
Subject: [PATCH 3/3] Update
 
clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst

Co-authored-by: EugeneZelenko <[email protected]>
---
 .../clang-tidy/checks/performance/string-view-conversions.rst    | 1 -
 1 file changed, 1 deletion(-)

diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
index 74708c9e6a353..51f86a9fdae79 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/performance/string-view-conversions.rst
@@ -10,7 +10,6 @@ And fixes them.
 
 Before:
 
-
 .. code-block:: c++
 
     void foo(int p1, std::string_view p2, double p3);

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

Reply via email to