Skip to content

Commit fa38527

Browse files
authored
[libc++] Add ABI tests for unordered_{map,set} (#107200)
These are used to ensure #76756 is correct.
1 parent b44d9e5 commit fa38527

File tree

3 files changed

+267
-0
lines changed

3 files changed

+267
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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: libcpp-has-abi-fix-unordered-container-size-type
10+
11+
#include <cstdint>
12+
#include <unordered_map>
13+
14+
#include "min_allocator.h"
15+
#include "test_allocator.h"
16+
#include "test_macros.h"
17+
18+
template <class T>
19+
class small_pointer {
20+
std::uint16_t offset;
21+
};
22+
23+
template <class T>
24+
class small_iter_allocator {
25+
public:
26+
using value_type = T;
27+
using pointer = small_pointer<T>;
28+
using size_type = std::uint16_t;
29+
using difference_type = std::int16_t;
30+
31+
small_iter_allocator() TEST_NOEXCEPT {}
32+
33+
template <class U>
34+
small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
35+
36+
T* allocate(std::size_t n);
37+
void deallocate(T* p, std::size_t);
38+
39+
friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
40+
friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
41+
};
42+
43+
template <class T>
44+
class final_small_iter_allocator final {
45+
public:
46+
using value_type = T;
47+
using pointer = small_pointer<T>;
48+
using size_type = std::uint16_t;
49+
using difference_type = std::int16_t;
50+
51+
final_small_iter_allocator() TEST_NOEXCEPT {}
52+
53+
template <class U>
54+
final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
55+
56+
T* allocate(std::size_t n);
57+
void deallocate(T* p, std::size_t);
58+
59+
friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
60+
friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
61+
};
62+
63+
template <class T, class Alloc>
64+
using unordered_map_alloc = std::unordered_map<T, T, std::hash<T>, std::equal_to<T>, Alloc>;
65+
66+
#if __SIZE_WIDTH__ == 64
67+
68+
static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 40, "");
69+
static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 40, "");
70+
static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 64, "");
71+
static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
72+
static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
73+
74+
static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 40, "");
75+
static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 40, "");
76+
static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 64, "");
77+
static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
78+
static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
79+
80+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 8, "");
81+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 8, "");
82+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 8, "");
83+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
84+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
85+
86+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 8, "");
87+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 8, "");
88+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 8, "");
89+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
90+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
91+
"");
92+
93+
struct TEST_ALIGNAS(32) AlignedHash {};
94+
struct UnalignedEqualTo {};
95+
96+
static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 96, "");
97+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32, "");
98+
99+
#elif __SIZE_WIDTH__ == 32
100+
101+
static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 20, "");
102+
static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 20, "");
103+
static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 44, "");
104+
static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
105+
static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
106+
107+
static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 20, "");
108+
static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 20, "");
109+
static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 44, "");
110+
static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
111+
static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
112+
113+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 4, "");
114+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 4, "");
115+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 4, "");
116+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
117+
static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
118+
119+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 4, "");
120+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 4, "");
121+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 4, "");
122+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
123+
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
124+
"");
125+
126+
struct TEST_ALIGNAS(32) AlignedHash {};
127+
struct UnalignedEqualTo {};
128+
129+
static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 96);
130+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32);
131+
132+
#else
133+
# error std::size_t has an unexpected size
134+
#endif
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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: libcpp-has-abi-fix-unordered-container-size-type
10+
11+
#include <cstdint>
12+
#include <unordered_set>
13+
14+
#include "min_allocator.h"
15+
#include "test_allocator.h"
16+
#include "test_macros.h"
17+
18+
template <class T>
19+
class small_pointer {
20+
std::uint16_t offset;
21+
};
22+
23+
template <class T>
24+
class small_iter_allocator {
25+
public:
26+
using value_type = T;
27+
using pointer = small_pointer<T>;
28+
using size_type = std::uint16_t;
29+
using difference_type = std::int16_t;
30+
31+
small_iter_allocator() TEST_NOEXCEPT {}
32+
33+
template <class U>
34+
small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
35+
36+
T* allocate(std::size_t n);
37+
void deallocate(T* p, std::size_t);
38+
39+
friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
40+
friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
41+
};
42+
43+
template <class T>
44+
class final_small_iter_allocator final {
45+
public:
46+
using value_type = T;
47+
using pointer = small_pointer<T>;
48+
using size_type = std::uint16_t;
49+
using difference_type = std::int16_t;
50+
51+
final_small_iter_allocator() TEST_NOEXCEPT {}
52+
53+
template <class U>
54+
final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
55+
56+
T* allocate(std::size_t n);
57+
void deallocate(T* p, std::size_t);
58+
59+
friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
60+
friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
61+
};
62+
63+
template <class T, class Alloc>
64+
using unordered_set_alloc = std::unordered_set<T, std::hash<T>, std::equal_to<T>, Alloc>;
65+
66+
#if __SIZE_WIDTH__ == 64
67+
68+
static_assert(sizeof(unordered_set_alloc<int, std::allocator<int> >) == 40, "");
69+
static_assert(sizeof(unordered_set_alloc<int, min_allocator<int> >) == 40, "");
70+
static_assert(sizeof(unordered_set_alloc<int, test_allocator<int> >) == 64, "");
71+
static_assert(sizeof(unordered_set_alloc<int, small_iter_allocator<int> >) == 12, "");
72+
static_assert(sizeof(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 16, "");
73+
74+
static_assert(sizeof(unordered_set_alloc<char, std::allocator<char> >) == 40, "");
75+
static_assert(sizeof(unordered_set_alloc<char, min_allocator<char> >) == 40, "");
76+
static_assert(sizeof(unordered_set_alloc<char, test_allocator<char> >) == 64, "");
77+
static_assert(sizeof(unordered_set_alloc<char, small_iter_allocator<char> >) == 12, "");
78+
static_assert(sizeof(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 16, "");
79+
80+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, std::allocator<int> >) == 8, "");
81+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, min_allocator<int> >) == 8, "");
82+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, test_allocator<int> >) == 8, "");
83+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, small_iter_allocator<int> >) == 4, "");
84+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 4, "");
85+
86+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, std::allocator<char> >) == 8, "");
87+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, min_allocator<char> >) == 8, "");
88+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, test_allocator<char> >) == 8, "");
89+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, small_iter_allocator<char> >) == 4, "");
90+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 4, "");
91+
92+
struct TEST_ALIGNAS(32) AlignedHash {};
93+
struct UnalignedEqualTo {};
94+
95+
static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 96, "");
96+
static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32, "");
97+
98+
#elif __SIZE_WIDTH__ == 32
99+
100+
static_assert(sizeof(unordered_set_alloc<int, std::allocator<int> >) == 20, "");
101+
static_assert(sizeof(unordered_set_alloc<int, min_allocator<int> >) == 20, "");
102+
static_assert(sizeof(unordered_set_alloc<int, test_allocator<int> >) == 44, "");
103+
static_assert(sizeof(unordered_set_alloc<int, small_iter_allocator<int> >) == 12, "");
104+
static_assert(sizeof(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 16, "");
105+
106+
static_assert(sizeof(unordered_set_alloc<char, std::allocator<char> >) == 20, "");
107+
static_assert(sizeof(unordered_set_alloc<char, min_allocator<char> >) == 20, "");
108+
static_assert(sizeof(unordered_set_alloc<char, test_allocator<char> >) == 44, "");
109+
static_assert(sizeof(unordered_set_alloc<char, small_iter_allocator<char> >) == 12, "");
110+
static_assert(sizeof(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 16, "");
111+
112+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, std::allocator<int> >) == 4, "");
113+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, min_allocator<int> >) == 4, "");
114+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, test_allocator<int> >) == 4, "");
115+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, small_iter_allocator<int> >) == 4, "");
116+
static_assert(TEST_ALIGNOF(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 4, "");
117+
118+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, std::allocator<char> >) == 4, "");
119+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, min_allocator<char> >) == 4, "");
120+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, test_allocator<char> >) == 4, "");
121+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, small_iter_allocator<char> >) == 4, "");
122+
static_assert(TEST_ALIGNOF(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 4, "");
123+
124+
struct TEST_ALIGNAS(32) AlignedHash {};
125+
struct UnalignedEqualTo {};
126+
127+
static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 96);
128+
static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32);
129+
130+
#else
131+
# error std::size_t has an unexpected size
132+
#endif

libcxx/utils/libcxx/test/features.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ def _mingwSupportsModules(cfg):
374374
"_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
375375
"_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string",
376376
"_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector",
377+
"_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type",
377378
"_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor",
378379
"_LIBCPP_HAS_NO_FILESYSTEM": "no-filesystem",
379380
"_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device",

0 commit comments

Comments
 (0)