[clang-tools-extra] [clang-tidy] Temp fix for assert in performance-string-view-conversions (PR #179027)

Zinovy Nis via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 31 02:15:49 PST 2026


https://github.com/irishrover created https://github.com/llvm/llvm-project/pull/179027

I faced with assertions while analyzing Chromium code:  ParamExpr->getSourceRange() != RedundantExpr->getSourceRange()

- https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/webui/policy/policy_ui.cc;l=323
- https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/web_applications/navigation_capturing_process.cc;l=346
- etc

I was able to reproduce it in tests by adding `operator basic_string_view<C, T>() const;` to `std::string` mock the same as real `std::string` in STL has.

I'm trying to find a fix for the matcher to workaround this assert. WIP.

>From 44f089938e83cc14ca02e8868fab63f00bd29b12 Mon Sep 17 00:00:00 2001
From: Zinovy Nis <zinovy.nis at gmail.com>
Date: Sat, 31 Jan 2026 12:56:30 +0300
Subject: [PATCH] [clang-tidy] Temp fix for assert in
 performance-string-view-conversions

---
 .../StringViewConversionsCheck.cpp            |  3 ++-
 .../clang-tidy/checkers/Inputs/Headers/string |  2 +-
 .../string-view-conversions-cxx20.cpp         |  6 +++---
 .../performance/string-view-conversions.cpp   | 20 +++++++++----------
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
index f09f6f203bf3a..12cfe1f7b4cbf 100644
--- a/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/StringViewConversionsCheck.cpp
@@ -92,7 +92,8 @@ void StringViewConversionsCheck::check(const MatchFinder::MatchResult &Result) {
   // 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").
-  assert(ParamExpr->getSourceRange() == RedundantExpr->getSourceRange());
+  if (ParamExpr->getSourceRange() != RedundantExpr->getSourceRange())
+    return;
 
   const StringRef OriginalText = Lexer::getSourceText(
       CharSourceRange::getTokenRange(OriginalExpr->getSourceRange()),
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 c3fd2cf6c1ff7..7de709d07f2df 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string
@@ -27,6 +27,7 @@ struct basic_string {
   basic_string(const C *p, size_type count);
   basic_string(const C *b, const C *e);
   basic_string(size_t, C);
+  operator basic_string_view<C, T>() const;
 
   ~basic_string();
 
@@ -108,7 +109,6 @@ 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;
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions-cxx20.cpp
index 1a49883dad100..3b7883ec80a56 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions-cxx20.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/string-view-conversions-cxx20.cpp
@@ -14,14 +14,14 @@ void positive(std::string_view sv, std::wstring_view wsv) {
   // [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' (aka 'basic_string<char8_t>') and then back to 'std::u8string_view' (aka 'basic_string_view<char8_t>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant conversion to 'std::u8string' (aka 'basic_string<char8_t>') and then back to 'basic_string_view<char8_t, std::char_traits<char8_t>>' [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' (aka 'basic_string<char16_t>') and then back to 'std::u16string_view' (aka 'basic_string_view<char16_t>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant conversion to 'std::u16string' (aka 'basic_string<char16_t>') and then back to 'basic_string_view<char16_t, std::char_traits<char16_t>>' [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' (aka 'basic_string<char32_t>') and then back to 'std::u32string_view' (aka 'basic_string_view<char32_t>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant conversion to 'std::u32string' (aka 'basic_string<char32_t>') and then back to 'basic_string_view<char32_t, std::char_traits<char32_t>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_u32sv(42, U"Hello, world", 3.14);
 }
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
index bfd5521b39d72..887e0cb8ff9a5 100644
--- 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
@@ -46,52 +46,52 @@ 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' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [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' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant  conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [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' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [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' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [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' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_sv(42, arr, 3.14);
 
   foo_sv(42, std::string(foo_sv(42)), 3.14);
-  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_sv(42, foo_sv(42), 3.14);
 
   std::string s = "hello";
   foo_sv(42, std::string(s), 3.14);
-  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_sv(42, s, 3.14);
 
   foo_sv(42, std::string{s}, 3.14);
-  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'std::string_view' (aka 'basic_string_view<char>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant conversion to 'std::string' (aka 'basic_string<char>') and then back to 'basic_string_view<char, std::char_traits<char>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_sv(42, s, 3.14);
 
   // wstring(wstring_view)
   //
   foo_wsv(42, std::wstring(wsv), 3.14);
-  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant conversion to 'std::wstring' (aka 'basic_string<wchar_t>') and then back to 'std::wstring_view' (aka 'basic_string_view<wchar_t>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant conversion to 'std::wstring' (aka 'basic_string<wchar_t>') and then back to 'basic_string_view<wchar_t, std::char_traits<wchar_t>>' [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' (aka 'basic_string<wchar_t>') and then back to 'std::wstring_view' (aka 'basic_string_view<wchar_t>') [performance-string-view-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant conversion to 'std::wstring' (aka 'basic_string<wchar_t>') and then back to 'basic_string_view<wchar_t, std::char_traits<wchar_t>>' [performance-string-view-conversions]
   // CHECK-FIXES: foo_wsv(42, wptr, 3.14);
 }
 



More information about the cfe-commits mailing list