[libcxx-commits] [libcxx] 9146ef5 - [libc++][string] Assert resize_and_overwrite operation returns integer-like type (#162030)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 9 16:32:54 PDT 2025
Author: NagaChaitanya Vellanki
Date: 2025-10-10T07:32:50+08:00
New Revision: 9146ef5df0543f08a86686cfeb3bd1ea7338f4c6
URL: https://github.com/llvm/llvm-project/commit/9146ef5df0543f08a86686cfeb3bd1ea7338f4c6
DIFF: https://github.com/llvm/llvm-project/commit/9146ef5df0543f08a86686cfeb3bd1ea7338f4c6.diff
LOG: [libc++][string] Assert resize_and_overwrite operation returns integer-like type (#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
Added:
libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.verify.cpp
Modified:
libcxx/include/string
libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/string b/libcxx/include/string
index f5e05d885b6c5..8f80afbc2fd37 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1312,6 +1312,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..e5c196385094b 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
@@ -21,6 +21,7 @@
#include "make_string.h"
#include "test_macros.h"
#include "asan_testing.h"
+#include "type_algorithms.h"
template <class S>
constexpr void test_appending(std::size_t k, size_t N, size_t new_capacity) {
@@ -77,17 +78,30 @@ 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() {
+ types::for_each(types::integer_types(), []<typename IntegerType> {
+ std::string s;
+ s.resize_and_overwrite(10, [](char* p, std::size_t n) -> IntegerType {
+ std::fill(p, p + n, 'f');
+ return n;
+ });
+ assert(s.size() == 10);
+ });
+ return true;
}
int main(int, char**) {
@@ -105,5 +119,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..323f49b72c2c8
--- /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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <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