Skip to content

Commit 387860e

Browse files
authored
[libc++] Add ABI tests for introducing _LIBCPP_COMPRESSED_ELEMENT (#156416)
#134253 refactors a few classes to use `[[no_unique_address]]` instead of the EBO. This adds tests to ensure there are no ABI breaks.
1 parent e90e76e commit 387860e

File tree

3 files changed

+197
-9
lines changed

3 files changed

+197
-9
lines changed

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ struct user_struct {
8787
[[no_unique_address]] common_base_allocator<int> a;
8888
};
8989

90+
struct TEST_ALIGNAS(32) AlignedLess {};
91+
struct FinalLess final {};
92+
struct NonEmptyLess {
93+
int i;
94+
char c;
95+
};
96+
97+
static_assert(std::is_empty<std::__map_value_compare<int, std::pair<const int, int>, std::less<int> > >::value, "");
98+
static_assert(std::is_empty<std::__map_value_compare<int, std::pair<const int, int>, AlignedLess> >::value, "");
99+
static_assert(!std::is_empty<std::__map_value_compare<int, std::pair<const int, int>, FinalLess> >::value, "");
100+
static_assert(!std::is_empty<std::__map_value_compare<int, std::pair<const int, int>, NonEmptyLess> >::value, "");
101+
90102
#if __SIZE_WIDTH__ == 64
91103
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
92104
# ifdef TEST_COMPILER_GCC
@@ -120,10 +132,13 @@ static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char,
120132
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
121133
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
122134

123-
struct TEST_ALIGNAS(32) AlignedLess {};
124-
125135
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64, "");
136+
static_assert(sizeof(std::map<int, int, FinalLess>) == 32, "");
137+
static_assert(sizeof(std::map<int, int, NonEmptyLess>) == 32, "");
138+
126139
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32, "");
140+
static_assert(TEST_ALIGNOF(std::map<int, int, FinalLess>) == 8, "");
141+
static_assert(TEST_ALIGNOF(std::map<int, int, NonEmptyLess>) == 8, "");
127142

128143
#elif __SIZE_WIDTH__ == 32
129144
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
@@ -158,10 +173,13 @@ static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char,
158173
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
159174
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
160175

161-
struct TEST_ALIGNAS(32) AlignedLess {};
176+
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64, "");
177+
static_assert(sizeof(std::map<int, int, FinalLess>) == 16, "");
178+
static_assert(sizeof(std::map<int, int, NonEmptyLess>) == 20, "");
162179

163-
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64);
164-
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32);
180+
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32, "");
181+
static_assert(TEST_ALIGNOF(std::map<int, int, FinalLess>) == 4, "");
182+
static_assert(TEST_ALIGNOF(std::map<int, int, NonEmptyLess>) == 4, "");
165183

166184
#else
167185
# error std::size_t has an unexpected size

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

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,33 @@ struct user_struct {
9191
[[no_unique_address]] common_base_allocator<int> a;
9292
};
9393

94+
struct TEST_ALIGNAS(32) AlignedHash {};
95+
struct FinalHash final {};
96+
struct NonEmptyHash final {
97+
int i;
98+
char c;
99+
};
100+
struct UnalignedEqualTo {};
101+
struct FinalEqualTo final {};
102+
struct NonEmptyEqualTo {
103+
int i;
104+
char c;
105+
};
106+
107+
static_assert(std::is_empty<std::__unordered_map_hasher<int, std::pair<const int, int>, std::hash<int>, int> >::value,
108+
"");
109+
static_assert(std::is_empty<std::__unordered_map_hasher<int, std::pair<const int, int>, AlignedHash, int> >::value, "");
110+
static_assert(!std::is_empty<std::__unordered_map_hasher<int, std::pair<const int, int>, FinalHash, int> >::value, "");
111+
static_assert(!std::is_empty<std::__unordered_map_hasher<int, std::pair<const int, int>, NonEmptyHash, int> >::value,
112+
"");
113+
114+
static_assert(std::is_empty<std::__unordered_map_equal<int, std::pair<const int, int>, std::hash<int>, int> >::value,
115+
"");
116+
static_assert(std::is_empty<std::__unordered_map_equal<int, std::pair<const int, int>, AlignedHash, int> >::value, "");
117+
static_assert(!std::is_empty<std::__unordered_map_equal<int, std::pair<const int, int>, FinalHash, int> >::value, "");
118+
static_assert(!std::is_empty<std::__unordered_map_equal<int, std::pair<const int, int>, NonEmptyHash, int> >::value,
119+
"");
120+
94121
#if __SIZE_WIDTH__ == 64
95122
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
96123
# ifdef TEST_COMPILER_GCC
@@ -125,8 +152,20 @@ static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::p
125152
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
126153
"");
127154

128-
struct TEST_ALIGNAS(32) AlignedHash {};
129-
struct UnalignedEqualTo {};
155+
#ifdef TEST_COMPILER_GCC
156+
static_assert(sizeof(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 40, "");
157+
#else
158+
static_assert(sizeof(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 48, "");
159+
#endif
160+
static_assert(sizeof(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 48, "");
161+
static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 48, "");
162+
static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 56, "");
163+
164+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 8, "");
165+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 8, "");
166+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 8, "");
167+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 8, "");
168+
130169
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
131170
# ifdef TEST_COMPILER_GCC
132171
static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 64, "");
@@ -169,8 +208,15 @@ static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::p
169208
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
170209
"");
171210

172-
struct TEST_ALIGNAS(32) AlignedHash {};
173-
struct UnalignedEqualTo {};
211+
static_assert(sizeof(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 24, "");
212+
static_assert(sizeof(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 24, "");
213+
static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 28, "");
214+
static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 32, "");
215+
216+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 4, "");
217+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 4, "");
218+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 4, "");
219+
static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 4, "");
174220

175221
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
176222
# ifdef TEST_COMPILER_GCC
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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
10+
11+
// UNSUPPORTED: libcpp-abi-no-compressed-pair-padding
12+
13+
#include <tuple>
14+
#include <type_traits>
15+
16+
#include "test_macros.h"
17+
18+
struct S {};
19+
20+
struct Final final {};
21+
22+
struct NonEmpty {
23+
int i;
24+
char c;
25+
};
26+
27+
struct NonEmptyFinal final {
28+
int i;
29+
char c;
30+
};
31+
32+
struct TEST_ALIGNAS(16) Overaligned {};
33+
struct TEST_ALIGNAS(16) OveralignedFinal final {};
34+
35+
static_assert(std::is_empty<std::tuple<>>::value, "");
36+
static_assert(!std::is_empty<std::tuple<S>>::value, "");
37+
static_assert(!std::is_empty<std::tuple<S&>>::value, "");
38+
static_assert(!std::is_empty<std::tuple<S&&>>::value, "");
39+
static_assert(!std::is_empty<std::tuple<Final>>::value, "");
40+
static_assert(!std::is_empty<std::tuple<NonEmpty>>::value, "");
41+
static_assert(!std::is_empty<std::tuple<NonEmptyFinal>>::value, "");
42+
static_assert(!std::is_empty<std::tuple<Overaligned>>::value, "");
43+
static_assert(!std::is_empty<std::tuple<OveralignedFinal>>::value, "");
44+
45+
static_assert(sizeof(std::tuple<S>) == 1, "");
46+
static_assert(sizeof(std::tuple<S&>) == sizeof(void*), "");
47+
static_assert(sizeof(std::tuple<S&&>) == sizeof(void*), "");
48+
static_assert(sizeof(std::tuple<Final>) == 1, "");
49+
static_assert(sizeof(std::tuple<NonEmpty>) == 8, "");
50+
static_assert(sizeof(std::tuple<NonEmptyFinal>) == 8, "");
51+
static_assert(sizeof(std::tuple<Overaligned>) == 16, "");
52+
static_assert(sizeof(std::tuple<OveralignedFinal>) == 16, "");
53+
54+
static_assert(sizeof(std::tuple<S, S>) == 2, "");
55+
static_assert(sizeof(std::tuple<S&, S>) == sizeof(void*), "");
56+
static_assert(sizeof(std::tuple<S&&, S>) == sizeof(void*), "");
57+
static_assert(sizeof(std::tuple<Final, S>) == 1, "");
58+
static_assert(sizeof(std::tuple<NonEmpty, S>) == 8, "");
59+
static_assert(sizeof(std::tuple<NonEmptyFinal, S>) == 8, "");
60+
static_assert(sizeof(std::tuple<Overaligned, S>) == 16, "");
61+
static_assert(sizeof(std::tuple<OveralignedFinal, S>) == 16, "");
62+
63+
static_assert(sizeof(std::tuple<S, S&>) == sizeof(void*), "");
64+
static_assert(sizeof(std::tuple<S&, S&>) == 2 * sizeof(void*), "");
65+
static_assert(sizeof(std::tuple<S&&, S&>) == 2 * sizeof(void*), "");
66+
static_assert(sizeof(std::tuple<Final, S&>) == 2 * sizeof(void*), "");
67+
static_assert(sizeof(std::tuple<NonEmpty, S&>) == 8 + sizeof(void*), "");
68+
static_assert(sizeof(std::tuple<NonEmptyFinal, S&>) == 8 + sizeof(void*), "");
69+
static_assert(sizeof(std::tuple<Overaligned, S&>) == 16, "");
70+
static_assert(sizeof(std::tuple<OveralignedFinal, S&>) == 32, "");
71+
72+
static_assert(sizeof(std::tuple<S, S&&>) == sizeof(void*), "");
73+
static_assert(sizeof(std::tuple<S&, S&&>) == 2 * sizeof(void*), "");
74+
static_assert(sizeof(std::tuple<S&&, S&&>) == 2 * sizeof(void*), "");
75+
static_assert(sizeof(std::tuple<Final, S&&>) == 2 * sizeof(void*), "");
76+
static_assert(sizeof(std::tuple<NonEmpty, S&&>) == 8 + sizeof(void*), "");
77+
static_assert(sizeof(std::tuple<NonEmptyFinal, S&&>) == 8 + sizeof(void*), "");
78+
static_assert(sizeof(std::tuple<Overaligned, S&&>) == 16, "");
79+
static_assert(sizeof(std::tuple<OveralignedFinal, S&&>) == 32, "");
80+
81+
static_assert(sizeof(std::tuple<S, Final>) == 1, "");
82+
static_assert(sizeof(std::tuple<S&, Final>) == 2 * sizeof(void*), "");
83+
static_assert(sizeof(std::tuple<S&&, Final>) == 2 * sizeof(void*), "");
84+
static_assert(sizeof(std::tuple<Final, Final>) == 2, "");
85+
static_assert(sizeof(std::tuple<NonEmpty, Final>) == 12, "");
86+
static_assert(sizeof(std::tuple<NonEmptyFinal, Final>) == 12, "");
87+
static_assert(sizeof(std::tuple<Overaligned, Final>) == 16, "");
88+
static_assert(sizeof(std::tuple<OveralignedFinal, Final>) == 32, "");
89+
90+
static_assert(sizeof(std::tuple<S, NonEmpty>) == 8, "");
91+
static_assert(sizeof(std::tuple<S&, NonEmpty>) == sizeof(void*) + 8, "");
92+
static_assert(sizeof(std::tuple<S&&, NonEmpty>) == sizeof(void*) + 8, "");
93+
static_assert(sizeof(std::tuple<Final, NonEmpty>) == 12, "");
94+
static_assert(sizeof(std::tuple<NonEmpty, NonEmpty>) == 16, "");
95+
static_assert(sizeof(std::tuple<NonEmptyFinal, NonEmpty>) == 16, "");
96+
static_assert(sizeof(std::tuple<Overaligned, NonEmpty>) == 16, "");
97+
static_assert(sizeof(std::tuple<OveralignedFinal, NonEmpty>) == 32, "");
98+
99+
static_assert(sizeof(std::tuple<S, NonEmptyFinal>) == 8, "");
100+
static_assert(sizeof(std::tuple<S&, NonEmptyFinal>) == sizeof(void*) + 8, "");
101+
static_assert(sizeof(std::tuple<S&&, NonEmptyFinal>) == sizeof(void*) + 8, "");
102+
static_assert(sizeof(std::tuple<Final, NonEmptyFinal>) == 12, "");
103+
static_assert(sizeof(std::tuple<NonEmpty, NonEmptyFinal>) == 16, "");
104+
static_assert(sizeof(std::tuple<NonEmptyFinal, NonEmptyFinal>) == 16, "");
105+
static_assert(sizeof(std::tuple<Overaligned, NonEmptyFinal>) == 16, "");
106+
static_assert(sizeof(std::tuple<OveralignedFinal, NonEmptyFinal>) == 32, "");
107+
108+
static_assert(sizeof(std::tuple<S, Overaligned>) == 16, "");
109+
static_assert(sizeof(std::tuple<S&, Overaligned>) == 16, "");
110+
static_assert(sizeof(std::tuple<S&&, Overaligned>) == 16, "");
111+
static_assert(sizeof(std::tuple<Final, Overaligned>) == 16, "");
112+
static_assert(sizeof(std::tuple<NonEmpty, Overaligned>) == 16, "");
113+
static_assert(sizeof(std::tuple<NonEmptyFinal, Overaligned>) == 16, "");
114+
static_assert(sizeof(std::tuple<Overaligned, Overaligned>) == 32, "");
115+
static_assert(sizeof(std::tuple<OveralignedFinal, Overaligned>) == 16, "");
116+
117+
static_assert(sizeof(std::tuple<S, OveralignedFinal>) == 16, "");
118+
static_assert(sizeof(std::tuple<S&, OveralignedFinal>) == 32, "");
119+
static_assert(sizeof(std::tuple<S&&, OveralignedFinal>) == 32, "");
120+
static_assert(sizeof(std::tuple<Final, OveralignedFinal>) == 32, "");
121+
static_assert(sizeof(std::tuple<NonEmpty, OveralignedFinal>) == 32, "");
122+
static_assert(sizeof(std::tuple<NonEmptyFinal, OveralignedFinal>) == 32, "");
123+
static_assert(sizeof(std::tuple<Overaligned, OveralignedFinal>) == 16, "");
124+
static_assert(sizeof(std::tuple<OveralignedFinal, OveralignedFinal>) == 32, "");

0 commit comments

Comments
 (0)