Skip to content

Commit f45b931

Browse files
author
git apple-llvm automerger
committed
Merge commit '5ec7fdf0c4e8' from llvm.org/release/21.x into stable/21.x
2 parents 806ebc6 + 5ec7fdf commit f45b931

File tree

10 files changed

+718
-0
lines changed

10 files changed

+718
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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-abi-no-compressed-pair-padding
10+
11+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
12+
13+
#include <cstdint>
14+
#include <map>
15+
16+
#include "min_allocator.h"
17+
#include "test_allocator.h"
18+
#include "test_macros.h"
19+
20+
template <class T>
21+
class small_pointer {
22+
std::uint16_t offset;
23+
};
24+
25+
template <class T>
26+
class small_iter_allocator {
27+
public:
28+
using value_type = T;
29+
using pointer = small_pointer<T>;
30+
using size_type = std::uint16_t;
31+
using difference_type = std::int16_t;
32+
33+
small_iter_allocator() TEST_NOEXCEPT {}
34+
35+
template <class U>
36+
small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
37+
38+
T* allocate(std::size_t n);
39+
void deallocate(T* p, std::size_t);
40+
41+
friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
42+
friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
43+
};
44+
45+
template <class T>
46+
class final_small_iter_allocator final {
47+
public:
48+
using value_type = T;
49+
using pointer = small_pointer<T>;
50+
using size_type = std::uint16_t;
51+
using difference_type = std::int16_t;
52+
53+
final_small_iter_allocator() TEST_NOEXCEPT {}
54+
55+
template <class U>
56+
final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
57+
58+
T* allocate(std::size_t n);
59+
void deallocate(T* p, std::size_t);
60+
61+
friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
62+
friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
63+
};
64+
65+
struct allocator_base {};
66+
67+
// Make sure that types with a common base type don't get broken. See https://llvm.org/PR154146
68+
template <class T>
69+
struct common_base_allocator : allocator_base {
70+
using value_type = T;
71+
72+
common_base_allocator() TEST_NOEXCEPT {}
73+
74+
template <class U>
75+
common_base_allocator(common_base_allocator<U>) TEST_NOEXCEPT {}
76+
77+
T* allocate(std::size_t n);
78+
void deallocate(T* p, std::size_t);
79+
80+
friend bool operator==(common_base_allocator, common_base_allocator) { return true; }
81+
friend bool operator!=(common_base_allocator, common_base_allocator) { return false; }
82+
};
83+
84+
template <class T, class Alloc>
85+
using map_alloc = std::map<T, T, std::less<T>, Alloc>;
86+
87+
struct user_struct {
88+
map_alloc<int, common_base_allocator<std::pair<const int, int> > > v;
89+
[[no_unique_address]] common_base_allocator<int> a;
90+
};
91+
92+
#if __SIZE_WIDTH__ == 64
93+
static_assert(sizeof(user_struct) == 32, "");
94+
static_assert(TEST_ALIGNOF(user_struct) == 8, "");
95+
96+
static_assert(sizeof(map_alloc<int, std::allocator<std::pair<const int, int> > >) == 24, "");
97+
static_assert(sizeof(map_alloc<int, min_allocator<std::pair<const int, int> > >) == 24, "");
98+
static_assert(sizeof(map_alloc<int, test_allocator<std::pair<const int, int> > >) == 40, "");
99+
static_assert(sizeof(map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 6, "");
100+
static_assert(sizeof(map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 8, "");
101+
102+
static_assert(sizeof(map_alloc<char, std::allocator<std::pair<const char, char> > >) == 24, "");
103+
static_assert(sizeof(map_alloc<char, min_allocator<std::pair<const char, char> > >) == 24, "");
104+
static_assert(sizeof(map_alloc<char, test_allocator<std::pair<const char, char> > >) == 40, "");
105+
static_assert(sizeof(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 6, "");
106+
static_assert(sizeof(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 8, "");
107+
108+
static_assert(TEST_ALIGNOF(map_alloc<int, std::allocator<std::pair<const int, int> > >) == 8, "");
109+
static_assert(TEST_ALIGNOF(map_alloc<int, min_allocator<std::pair<const int, int> > >) == 8, "");
110+
static_assert(TEST_ALIGNOF(map_alloc<int, test_allocator<std::pair<const int, int> > >) == 8, "");
111+
static_assert(TEST_ALIGNOF(map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 2, "");
112+
static_assert(TEST_ALIGNOF(map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 2, "");
113+
114+
static_assert(TEST_ALIGNOF(map_alloc<char, std::allocator<std::pair<const char, char> > >) == 8, "");
115+
static_assert(TEST_ALIGNOF(map_alloc<char, min_allocator<std::pair<const char, char> > >) == 8, "");
116+
static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char, char> > >) == 8, "");
117+
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
118+
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
119+
120+
struct TEST_ALIGNAS(32) AlignedLess {};
121+
122+
// This part of the ABI has been broken between LLVM 19 and LLVM 20.
123+
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64, "");
124+
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32, "");
125+
126+
#elif __SIZE_WIDTH__ == 32
127+
static_assert(sizeof(user_struct) == 16, "");
128+
static_assert(TEST_ALIGNOF(user_struct) == 4, "");
129+
130+
static_assert(sizeof(map_alloc<int, std::allocator<std::pair<const int, int> > >) == 12, "");
131+
static_assert(sizeof(map_alloc<int, min_allocator<std::pair<const int, int> > >) == 12, "");
132+
static_assert(sizeof(map_alloc<int, test_allocator<std::pair<const int, int> > >) == 24, "");
133+
static_assert(sizeof(map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 6, "");
134+
static_assert(sizeof(map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 8, "");
135+
136+
static_assert(sizeof(map_alloc<char, std::allocator<std::pair<const char, char> > >) == 12, "");
137+
static_assert(sizeof(map_alloc<char, min_allocator<std::pair<const char, char> > >) == 12, "");
138+
static_assert(sizeof(map_alloc<char, test_allocator<std::pair<const char, char> > >) == 24, "");
139+
static_assert(sizeof(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 6, "");
140+
static_assert(sizeof(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 8, "");
141+
142+
static_assert(TEST_ALIGNOF(map_alloc<int, std::allocator<std::pair<const int, int> > >) == 4, "");
143+
static_assert(TEST_ALIGNOF(map_alloc<int, min_allocator<std::pair<const int, int> > >) == 4, "");
144+
static_assert(TEST_ALIGNOF(map_alloc<int, test_allocator<std::pair<const int, int> > >) == 4, "");
145+
static_assert(TEST_ALIGNOF(map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 2, "");
146+
static_assert(TEST_ALIGNOF(map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 2, "");
147+
148+
static_assert(TEST_ALIGNOF(map_alloc<char, std::allocator<std::pair<const char, char> > >) == 4, "");
149+
static_assert(TEST_ALIGNOF(map_alloc<char, min_allocator<std::pair<const char, char> > >) == 4, "");
150+
static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char, char> > >) == 4, "");
151+
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
152+
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
153+
154+
struct TEST_ALIGNAS(32) AlignedLess {};
155+
156+
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64);
157+
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32);
158+
159+
#else
160+
# error std::size_t has an unexpected size
161+
#endif
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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-abi-no-compressed-pair-padding
10+
11+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
12+
13+
#include <cstdint>
14+
#include <set>
15+
16+
#include "min_allocator.h"
17+
#include "test_allocator.h"
18+
#include "test_macros.h"
19+
20+
template <class T>
21+
class small_pointer {
22+
std::uint16_t offset;
23+
};
24+
25+
template <class T>
26+
class small_iter_allocator {
27+
public:
28+
using value_type = T;
29+
using pointer = small_pointer<T>;
30+
using size_type = std::uint16_t;
31+
using difference_type = std::int16_t;
32+
33+
small_iter_allocator() TEST_NOEXCEPT {}
34+
35+
template <class U>
36+
small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
37+
38+
T* allocate(std::size_t n);
39+
void deallocate(T* p, std::size_t);
40+
41+
friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
42+
friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
43+
};
44+
45+
template <class T>
46+
class final_small_iter_allocator final {
47+
public:
48+
using value_type = T;
49+
using pointer = small_pointer<T>;
50+
using size_type = std::uint16_t;
51+
using difference_type = std::int16_t;
52+
53+
final_small_iter_allocator() TEST_NOEXCEPT {}
54+
55+
template <class U>
56+
final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
57+
58+
T* allocate(std::size_t n);
59+
void deallocate(T* p, std::size_t);
60+
61+
friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
62+
friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
63+
};
64+
65+
struct allocator_base {};
66+
67+
// Make sure that types with a common base type don't get broken. See https://llvm.org/PR154146
68+
template <class T>
69+
struct common_base_allocator : allocator_base {
70+
using value_type = T;
71+
72+
common_base_allocator() TEST_NOEXCEPT {}
73+
74+
template <class U>
75+
common_base_allocator(common_base_allocator<U>) TEST_NOEXCEPT {}
76+
77+
T* allocate(std::size_t n);
78+
void deallocate(T* p, std::size_t);
79+
80+
friend bool operator==(common_base_allocator, common_base_allocator) { return true; }
81+
friend bool operator!=(common_base_allocator, common_base_allocator) { return false; }
82+
};
83+
84+
template <class T, class Alloc>
85+
using set_alloc = std::set<T, std::less<T>, Alloc>;
86+
87+
struct user_struct {
88+
set_alloc<int, common_base_allocator<int> > v;
89+
[[no_unique_address]] common_base_allocator<int> a;
90+
};
91+
92+
#if __SIZE_WIDTH__ == 64
93+
static_assert(sizeof(user_struct) == 32, "");
94+
static_assert(TEST_ALIGNOF(user_struct) == 8, "");
95+
96+
static_assert(sizeof(set_alloc<int, std::allocator<int> >) == 24, "");
97+
static_assert(sizeof(set_alloc<int, min_allocator<int> >) == 24, "");
98+
static_assert(sizeof(set_alloc<int, test_allocator<int> >) == 40, "");
99+
static_assert(sizeof(set_alloc<int, small_iter_allocator<int> >) == 6, "");
100+
static_assert(sizeof(set_alloc<int, final_small_iter_allocator<int> >) == 8, "");
101+
102+
static_assert(sizeof(set_alloc<char, std::allocator<char> >) == 24, "");
103+
static_assert(sizeof(set_alloc<char, min_allocator<char> >) == 24, "");
104+
static_assert(sizeof(set_alloc<char, test_allocator<char> >) == 40, "");
105+
static_assert(sizeof(set_alloc<char, small_iter_allocator<char> >) == 6, "");
106+
static_assert(sizeof(set_alloc<char, final_small_iter_allocator<char> >) == 8, "");
107+
108+
static_assert(TEST_ALIGNOF(set_alloc<int, std::allocator<int> >) == 8, "");
109+
static_assert(TEST_ALIGNOF(set_alloc<int, min_allocator<int> >) == 8, "");
110+
static_assert(TEST_ALIGNOF(set_alloc<int, test_allocator<int> >) == 8, "");
111+
static_assert(TEST_ALIGNOF(set_alloc<int, small_iter_allocator<int> >) == 2, "");
112+
static_assert(TEST_ALIGNOF(set_alloc<int, final_small_iter_allocator<int> >) == 2, "");
113+
114+
static_assert(TEST_ALIGNOF(set_alloc<char, std::allocator<char> >) == 8, "");
115+
static_assert(TEST_ALIGNOF(set_alloc<char, min_allocator<char> >) == 8, "");
116+
static_assert(TEST_ALIGNOF(set_alloc<char, test_allocator<char> >) == 8, "");
117+
static_assert(TEST_ALIGNOF(set_alloc<char, small_iter_allocator<char> >) == 2, "");
118+
static_assert(TEST_ALIGNOF(set_alloc<char, final_small_iter_allocator<char> >) == 2, "");
119+
120+
struct TEST_ALIGNAS(32) AlignedLess {};
121+
122+
// This part of the ABI has been broken between LLVM 19 and LLVM 20.
123+
static_assert(sizeof(std::set<int, AlignedLess>) == 64, "");
124+
static_assert(TEST_ALIGNOF(std::set<int, AlignedLess>) == 32, "");
125+
126+
#elif __SIZE_WIDTH__ == 32
127+
static_assert(sizeof(user_struct) == 16, "");
128+
static_assert(TEST_ALIGNOF(user_struct) == 4, "");
129+
130+
static_assert(sizeof(set_alloc<int, std::allocator<int> >) == 12, "");
131+
static_assert(sizeof(set_alloc<int, min_allocator<int> >) == 12, "");
132+
static_assert(sizeof(set_alloc<int, test_allocator<int> >) == 24, "");
133+
static_assert(sizeof(set_alloc<int, small_iter_allocator<int> >) == 6, "");
134+
static_assert(sizeof(set_alloc<int, final_small_iter_allocator<int> >) == 8, "");
135+
136+
static_assert(sizeof(set_alloc<char, std::allocator<char> >) == 12, "");
137+
static_assert(sizeof(set_alloc<char, min_allocator<char> >) == 12, "");
138+
static_assert(sizeof(set_alloc<char, test_allocator<char> >) == 24, "");
139+
static_assert(sizeof(set_alloc<char, small_iter_allocator<char> >) == 6, "");
140+
static_assert(sizeof(set_alloc<char, final_small_iter_allocator<char> >) == 8, "");
141+
142+
static_assert(TEST_ALIGNOF(set_alloc<int, std::allocator<int> >) == 4, "");
143+
static_assert(TEST_ALIGNOF(set_alloc<int, min_allocator<int> >) == 4, "");
144+
static_assert(TEST_ALIGNOF(set_alloc<int, test_allocator<int> >) == 4, "");
145+
static_assert(TEST_ALIGNOF(set_alloc<int, small_iter_allocator<int> >) == 2, "");
146+
static_assert(TEST_ALIGNOF(set_alloc<int, final_small_iter_allocator<int> >) == 2, "");
147+
148+
static_assert(TEST_ALIGNOF(set_alloc<char, std::allocator<char> >) == 4, "");
149+
static_assert(TEST_ALIGNOF(set_alloc<char, min_allocator<char> >) == 4, "");
150+
static_assert(TEST_ALIGNOF(set_alloc<char, test_allocator<char> >) == 4, "");
151+
static_assert(TEST_ALIGNOF(set_alloc<char, small_iter_allocator<char> >) == 2, "");
152+
static_assert(TEST_ALIGNOF(set_alloc<char, final_small_iter_allocator<char> >) == 2, "");
153+
154+
struct TEST_ALIGNAS(32) AlignedLess {};
155+
156+
static_assert(sizeof(std::set<int, AlignedLess>) == 64);
157+
static_assert(TEST_ALIGNOF(std::set<int, AlignedLess>) == 32);
158+
159+
#else
160+
# error std::size_t has an unexpected size
161+
#endif

libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,36 @@ class final_small_iter_allocator final {
6666
friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
6767
};
6868

69+
struct allocator_base {};
70+
71+
// Make sure that types with a common base type don't get broken. See https://llvm.org/PR154146
72+
template <class T>
73+
struct common_base_allocator : allocator_base {
74+
using value_type = T;
75+
76+
common_base_allocator() TEST_NOEXCEPT {}
77+
78+
template <class U>
79+
common_base_allocator(common_base_allocator<U>) TEST_NOEXCEPT {}
80+
81+
T* allocate(std::size_t n);
82+
void deallocate(T* p, std::size_t);
83+
84+
friend bool operator==(common_base_allocator, common_base_allocator) { return true; }
85+
friend bool operator!=(common_base_allocator, common_base_allocator) { return false; }
86+
};
87+
6988
template <class T, class Alloc>
7089
using unordered_map_alloc = std::unordered_map<T, T, std::hash<T>, std::equal_to<T>, Alloc>;
7190

91+
struct user_struct {
92+
unordered_map_alloc<int, common_base_allocator<std::pair<const int, int> > > v;
93+
[[no_unique_address]] common_base_allocator<int> a;
94+
};
95+
7296
#if __SIZE_WIDTH__ == 64
97+
static_assert(sizeof(user_struct) == 48, "");
98+
static_assert(TEST_ALIGNOF(user_struct) == 8, "");
7399

74100
static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 40, "");
75101
static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 40, "");
@@ -104,6 +130,8 @@ static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>
104130
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32, "");
105131

106132
#elif __SIZE_WIDTH__ == 32
133+
static_assert(sizeof(user_struct) == 24, "");
134+
static_assert(TEST_ALIGNOF(user_struct) == 4, "");
107135

108136
static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 20, "");
109137
static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 20, "");

0 commit comments

Comments
 (0)