[libcxx-commits] [libcxx] [libc++][string] Assert resize_and_overwrite operation returns integer-like type (PR #162030)

NagaChaitanya Vellanki via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 6 21:53:02 PDT 2025


https://github.com/chaitanyav updated https://github.com/llvm/llvm-project/pull/162030

>From 26834f05770458ccbba53ec3444964c05d83fd29 Mon Sep 17 00:00:00 2001
From: NagaChaitanya Vellanki <pnagato at protonmail.com>
Date: Sun, 5 Oct 2025 15:33:46 -0700
Subject: [PATCH] [libc++][string] Assert resize_and_overwrite operation
 returns integer-like type

Verify that the operation passed to resize_and_overwrite returns an
integer-like type, matching the behavior of other standard library
implementations like GCC's libstdc++

Fixes #160577
---
 libcxx/include/string                         |  2 +
 .../resize_and_overwrite.pass.cpp             | 60 ++++++++++++++++++-
 .../resize_and_overwrite.verify.cpp           | 40 +++++++++++++
 3 files changed, 100 insertions(+), 2 deletions(-)
 create mode 100644 libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp

diff --git a/libcxx/include/string b/libcxx/include/string
index dc562e0207630..043533a4b599d 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1311,6 +1311,8 @@ public:
 #  if _LIBCPP_STD_VER >= 23
   template <class _Op>
   _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) {
+    using __result_type = decltype(std::move(__op)(data(), auto(__n)));
+    static_assert(__integer_like<__result_type>, "Operation return type must be integer-like");
     size_type __sz  = size();
     size_type __cap = capacity();
     if (__n > __cap)
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp
index abd284852a189..7d4a415227fae 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <cstddef>
 #include <memory>
 #include <string>
 
@@ -77,17 +78,65 @@ constexpr bool test() {
   return true;
 }
 
-void test_value_categories() {
+constexpr bool test_value_categories() {
   std::string s;
   s.resize_and_overwrite(10, [](char*&&, std::size_t&&) { return 0; });
   LIBCPP_ASSERT(is_string_asan_correct(s));
   s.resize_and_overwrite(10, [](char* const&, const std::size_t&) { return 0; });
   LIBCPP_ASSERT(is_string_asan_correct(s));
   struct RefQualified {
-    int operator()(char*, std::size_t) && { return 0; }
+    constexpr int operator()(char*, std::size_t) && { return 0; }
   };
   s.resize_and_overwrite(10, RefQualified{});
   LIBCPP_ASSERT(is_string_asan_correct(s));
+  return true;
+}
+
+constexpr bool test_integer_like_return_types() {
+  std::string s;
+
+  s.resize_and_overwrite(10, [](char* p, std::size_t n) -> int {
+    (void)n;
+    std::fill(p, p + 5, 'a');
+    return 5;
+  });
+  assert(s.size() == 5);
+
+  s.resize_and_overwrite(10, [](char* p, std::size_t n) -> unsigned int {
+    (void)n;
+    std::fill(p, p + 3, 'b');
+    return 3u;
+  });
+  assert(s.size() == 3);
+
+  s.resize_and_overwrite(10, [](char* p, std::size_t n) -> long {
+    (void)n;
+    std::fill(p, p + 7, 'c');
+    return 7l;
+  });
+  assert(s.size() == 7);
+
+  s.resize_and_overwrite(20, [](char* p, std::size_t n) -> unsigned long {
+    (void)n;
+    std::fill(p, p + 4, 'd');
+    return 4ul;
+  });
+  assert(s.size() == 4);
+
+  s.resize_and_overwrite(15, [](char* p, std::size_t n) -> long long {
+    (void)n;
+    std::fill(p, p + 8, 'e');
+    return 8ll;
+  });
+  assert(s.size() == 8);
+
+  s.resize_and_overwrite(10, [](char* p, std::size_t n) -> unsigned long long {
+    std::fill(p, p + n, 'f');
+    return n;
+  });
+  assert(s.size() == 10);
+
+  return true;
 }
 
 int main(int, char**) {
@@ -105,5 +154,12 @@ int main(int, char**) {
   test<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>>();
   static_assert(test<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>>());
 #endif
+
+  test_value_categories();
+  test_integer_like_return_types();
+
+  static_assert(test_value_categories());
+  static_assert(test_integer_like_return_types());
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp
new file mode 100644
index 0000000000000..1345fde296a20
--- /dev/null
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <string>
+
+// template<class Operation>
+// void resize_and_overwrite(size_type n, Operation op)
+
+// Verify that the operation's return type must be integer-like
+
+#include <string>
+
+void test_bool_return_type() {
+  std::string s;
+  s.resize_and_overwrite(10, [](char*, std::size_t) {
+    return true; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
+  });
+}
+
+void test_pointer_return_type() {
+  std::string s;
+  s.resize_and_overwrite(10, [](char* p, std::size_t) {
+    return p; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
+              // expected-error@*:* {{cannot initialize}}
+  });
+}
+
+void test_float_return_type() {
+  std::string s;
+  s.resize_and_overwrite(10, [](char*, std::size_t) {
+    return 5.0f; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
+  });
+}



More information about the libcxx-commits mailing list