Skip to content

Commit eea5e7e

Browse files
vitalybukaldionne
andauthored
[libc++][string] Add regression test for sized new/delete bug (#110210)
This is regression test for #90292. Allocator used in test is very similar to test_allocator. However, reproducer requires size_type of the string to be 64bit, but test_allocator uses 32bit. 32bit size_type makes `sizeof(string::__long)` to be 16, but the alignment issue fixed with #90292 is only triggered with default `sizeof(string::__long)` which is 24. Fixes #92128. --------- Co-authored-by: Louis Dionne <[email protected]>
1 parent 463a4f1 commit eea5e7e

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
// <string>
10+
11+
// Make sure the size we allocate and deallocate match. See https://github.com/llvm/llvm-project/pull/90292.
12+
13+
#include <string>
14+
#include <cassert>
15+
#include <cstdint>
16+
#include <type_traits>
17+
18+
#include "test_macros.h"
19+
20+
static int allocated_;
21+
22+
template <class T, class Sz>
23+
struct test_alloc {
24+
typedef Sz size_type;
25+
typedef typename std::make_signed<Sz>::type difference_type;
26+
typedef T value_type;
27+
typedef value_type* pointer;
28+
typedef const value_type* const_pointer;
29+
typedef typename std::add_lvalue_reference<value_type>::type reference;
30+
typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
31+
32+
template <class U>
33+
struct rebind {
34+
typedef test_alloc<U, Sz> other;
35+
};
36+
37+
TEST_CONSTEXPR_CXX14 pointer allocate(size_type n, const void* = nullptr) {
38+
allocated_ += n;
39+
return std::allocator<value_type>().allocate(n);
40+
}
41+
42+
TEST_CONSTEXPR_CXX14 void deallocate(pointer p, size_type s) {
43+
allocated_ -= s;
44+
std::allocator<value_type>().deallocate(p, s);
45+
}
46+
};
47+
48+
template <class Sz>
49+
void test() {
50+
for (int i = 1; i < 1000; ++i) {
51+
using Str = std::basic_string<char, std::char_traits<char>, test_alloc<char, Sz> >;
52+
{
53+
Str s(i, 't');
54+
assert(allocated_ == 0 || allocated_ >= i);
55+
}
56+
}
57+
assert(allocated_ == 0);
58+
}
59+
60+
int main(int, char**) {
61+
test<uint32_t>();
62+
test<uint64_t>();
63+
test<size_t>();
64+
65+
return 0;
66+
}

0 commit comments

Comments
 (0)