Skip to content

Commit 22188e2

Browse files
committed
[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
1 parent c793782 commit 22188e2

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

libcxx/include/string

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,8 @@ public:
13111311
# if _LIBCPP_STD_VER >= 23
13121312
template <class _Op>
13131313
_LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) {
1314+
using __result_type = decltype(__op(data(), auto(__n)));
1315+
static_assert(std::__integer_like<__result_type>, "Operation return type must be integer-like");
13141316
size_type __sz = size();
13151317
size_type __cap = capacity();
13161318
if (__n > __cap)

libcxx/test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ void test_value_categories() {
9090
LIBCPP_ASSERT(is_string_asan_correct(s));
9191
}
9292

93+
void test_integer_like_return_types() {
94+
std::string s;
95+
s.resize_and_overwrite(10, [](char*, std::size_t) -> int { return 5; });
96+
s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned int { return 5u; });
97+
s.resize_and_overwrite(10, [](char*, std::size_t) -> long { return 5l; });
98+
s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned long { return 5ul; });
99+
s.resize_and_overwrite(10, [](char*, std::size_t) -> long long { return 5ll; });
100+
s.resize_and_overwrite(10, [](char*, std::size_t) -> unsigned long long { return 5ull; });
101+
s.resize_and_overwrite(10, [](char*, std::size_t) -> std::size_t { return 5; });
102+
s.resize_and_overwrite(10, [](char*, std::size_t) -> std::ptrdiff_t { return 5; });
103+
}
104+
93105
int main(int, char**) {
94106
test<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>();
95107
test<std::basic_string<char8_t, std::char_traits<char8_t>, std::allocator<char8_t>>>();
@@ -105,5 +117,9 @@ int main(int, char**) {
105117
test<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>>();
106118
static_assert(test<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>>());
107119
#endif
120+
121+
test_value_categories();
122+
test_integer_like_return_types();
123+
108124
return 0;
109125
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <string>
12+
13+
// template<class Operation>
14+
// void resize_and_overwrite(size_type n, Operation op)
15+
16+
// Verify that the operation's return type must be integer-like
17+
18+
#include <string>
19+
20+
void test_bool_return_type() {
21+
std::string s;
22+
s.resize_and_overwrite(10, [](char*, std::size_t) {
23+
return true; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
24+
});
25+
}
26+
27+
void test_pointer_return_type() {
28+
std::string s;
29+
s.resize_and_overwrite(10, [](char* p, std::size_t) {
30+
return p; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
31+
});
32+
}
33+
34+
void test_float_return_type() {
35+
std::string s;
36+
s.resize_and_overwrite(10, [](char*, std::size_t) {
37+
return 5.0f; // expected-error-re@*:* {{{{(static_assertion|static assertion)}}{{.*}}integer-like}}
38+
});
39+
}

0 commit comments

Comments
 (0)