diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index cfbc78a31081aade18f2ab0e404e0b197183f1d3..99fdbeee5ad95092d170af27c4bc01f091cde6dc 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -592,9 +592,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	size_type _M_r;
       };
       _Terminator __term{this};
-      const size_type __n2 [[maybe_unused]] = __n;
-      __term._M_r = std::move(__op)(__p, __n);
-      _GLIBCXX_DEBUG_ASSERT(__term._M_r >= 0 && __term._M_r <= __n2);
+      auto __r = std::move(__op)(auto(__p), auto(__n));
+      static_assert(ranges::__detail::__is_integer_like<decltype(__r)>);
+      _GLIBCXX_DEBUG_ASSERT(__r >= 0 && __r <= __n);
+      __term._M_r = size_type(__r);
+      if (__term._M_r > __n)
+	__builtin_unreachable();
     }
 #endif // C++23
 
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
index a336b55f4a1105b8846640f4cddece588ae5957c..f716030dad7f5e8a647bdb0e1edcff0a372ff2d2 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
@@ -84,9 +84,11 @@ test03()
   VERIFY( s == std::string(42, 'a') );
   VERIFY( s[42] == '\0' );
 
-  s.resize_and_overwrite(0, [](auto&& p, auto&& n) {
-    static_assert( std::is_same_v<decltype(p), char*&> );
-    static_assert( std::is_same_v<decltype(n), std::string::size_type&> );
+  s.resize_and_overwrite(0, [](auto p, auto n) {
+    // N.B. these requirements were relaxed by LWG 3645:
+    // resize_and_overwrite is overspecified to call its callback with lvalues
+    static_assert( std::is_same_v<decltype(p), char*> );
+    static_assert( std::is_same_v<decltype(n), std::string::size_type> );
     return 0;
   });
 }