[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
Sun Oct 5 15:41:50 PDT 2025
https://github.com/chaitanyav created https://github.com/llvm/llvm-project/pull/162030
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
>From 22188e2cc98315e10abca64fc872970d7d4d256d 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 | 16 ++++++++
.../resize_and_overwrite.verify.cpp | 39 +++++++++++++++++++
3 files changed, 57 insertions(+)
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..00592e61547af 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(__op(data(), auto(__n)));
+ static_assert(std::__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..aa0b32bf3f589 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
@@ -90,6 +90,18 @@ void test_value_categories() {
LIBCPP_ASSERT(is_string_asan_correct(s));
}
+void test_integer_like_return_types() {
+ std::string s;
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> int { return 5; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned int { return 5u; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> long { return 5l; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned long { return 5ul; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> long long { return 5ll; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned long long { return 5ull; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> std::size_t { return 5; });
+ s.resize_and_overwrite(10, [](char*, std::size_t) -> std::ptrdiff_t { return 5; });
+}
+
int main(int, char**) {
test<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>();
test<std::basic_string<char8_t, std::char_traits<char8_t>, std::allocator<char8_t>>>();
@@ -105,5 +117,9 @@ 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();
+
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..00d04e56a3aea
--- /dev/null
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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}}
+ });
+}
+
+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