[libcxx-commits] [libcxx] [libc++] Add ABI tests for introducing _LIBCPP_COMPRESSED_ELEMENT (PR #156416)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 2 00:25:54 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/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.
>From d122fe9138b7fd3e112402294a81ab5644264093 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 2 Sep 2025 09:24:50 +0200
Subject: [PATCH] [libc++] Add ABI tests for introducing
_LIBCPP_COMPRESSED_ELEMENT
---
.../associative/map/abi.compile.pass.cpp | 23 ++++--
.../unord.map/abi.compile.pass.cpp | 36 ++++++++-
.../utilities/tuple/abi.compile.pass.cpp | 79 +++++++++++++++++++
3 files changed, 129 insertions(+), 9 deletions(-)
create mode 100644 libcxx/test/libcxx/utilities/tuple/abi.compile.pass.cpp
diff --git a/libcxx/test/libcxx/containers/associative/map/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/associative/map/abi.compile.pass.cpp
index e0598b4ff1746..8bd9afa75cbf2 100644
--- a/libcxx/test/libcxx/containers/associative/map/abi.compile.pass.cpp
+++ b/libcxx/test/libcxx/containers/associative/map/abi.compile.pass.cpp
@@ -87,6 +87,13 @@ struct user_struct {
[[no_unique_address]] common_base_allocator<int> a;
};
+struct TEST_ALIGNAS(32) AlignedLess {};
+struct FinalLess final {};
+struct NonEmptyLess {
+ int i;
+ char c;
+};
+
#if __SIZE_WIDTH__ == 64
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
# ifdef TEST_COMPILER_GCC
@@ -120,10 +127,13 @@ static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char,
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
-struct TEST_ALIGNAS(32) AlignedLess {};
-
static_assert(sizeof(std::map<int, int, AlignedLess>) == 64, "");
+static_assert(sizeof(std::map<int, int, FinalLess>) == 32, "");
+static_assert(sizeof(std::map<int, int, NonEmptyLess>) == 32, "");
+
static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32, "");
+static_assert(TEST_ALIGNOF(std::map<int, int, FinalLess>) == 8, "");
+static_assert(TEST_ALIGNOF(std::map<int, int, NonEmptyLess>) == 8, "");
#elif __SIZE_WIDTH__ == 32
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
@@ -158,10 +168,13 @@ static_assert(TEST_ALIGNOF(map_alloc<char, test_allocator<std::pair<const char,
static_assert(TEST_ALIGNOF(map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 2, "");
static_assert(TEST_ALIGNOF(map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 2, "");
-struct TEST_ALIGNAS(32) AlignedLess {};
+static_assert(sizeof(std::map<int, int, AlignedLess>) == 64, "");
+static_assert(sizeof(std::map<int, int, FinalLess>) == 16, "");
+static_assert(sizeof(std::map<int, int, NonEmptyLess>) == 20, "");
-static_assert(sizeof(std::map<int, int, AlignedLess>) == 64);
-static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32);
+static_assert(TEST_ALIGNOF(std::map<int, int, AlignedLess>) == 32, "");
+static_assert(TEST_ALIGNOF(std::map<int, int, FinalLess>) == 4, "");
+static_assert(TEST_ALIGNOF(std::map<int, int, NonEmptyLess>) == 4, "");
#else
# error std::size_t has an unexpected size
diff --git a/libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp
index 60c3e5bf31b00..43934bf3c5b47 100644
--- a/libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp
+++ b/libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp
@@ -91,6 +91,19 @@ struct user_struct {
[[no_unique_address]] common_base_allocator<int> a;
};
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct FinalHash final {};
+struct NonEmptyHash final {
+ int i;
+ char c;
+};
+struct UnalignedEqualTo {};
+struct FinalEqualTo final {};
+struct NonEmptyEqualTo {
+ int i;
+ char c;
+};
+
#if __SIZE_WIDTH__ == 64
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
# ifdef TEST_COMPILER_GCC
@@ -125,8 +138,16 @@ static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::p
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
"");
-struct TEST_ALIGNAS(32) AlignedHash {};
-struct UnalignedEqualTo {};
+static_assert(sizeof(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 48, "");
+static_assert(sizeof(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 48, "");
+static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 48, "");
+static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 56, "");
+
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 8, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 8, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 8, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 8, "");
+
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
# ifdef TEST_COMPILER_GCC
static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 64, "");
@@ -169,8 +190,15 @@ static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::p
static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
"");
-struct TEST_ALIGNAS(32) AlignedHash {};
-struct UnalignedEqualTo {};
+static_assert(sizeof(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 24, "");
+static_assert(sizeof(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 24, "");
+static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 28, "");
+static_assert(sizeof(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 32, "");
+
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, UnalignedEqualTo>) == 4, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, FinalHash, FinalEqualTo>) == 4, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, FinalEqualTo>) == 4, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, NonEmptyHash, NonEmptyEqualTo>) == 4, "");
// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
# ifdef TEST_COMPILER_GCC
diff --git a/libcxx/test/libcxx/utilities/tuple/abi.compile.pass.cpp b/libcxx/test/libcxx/utilities/tuple/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..a0774bb49b608
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/tuple/abi.compile.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: libcpp-abi-no-compressed-pair-padding
+
+#include <tuple>
+
+#include "test_macros.h"
+
+struct S {};
+
+struct Final final {};
+
+struct NonEmpty {
+ int i;
+ char c;
+};
+
+struct NonEmptyFinal final {
+ int i;
+ char c;
+};
+
+struct TEST_ALIGNAS(16) Overaligned {};
+struct TEST_ALIGNAS(16) OveralignedFinal final {};
+
+static_assert(sizeof(std::tuple<S>) == 1);
+static_assert(sizeof(std::tuple<Final>) == 1);
+static_assert(sizeof(std::tuple<NonEmpty>) == 8);
+static_assert(sizeof(std::tuple<NonEmptyFinal>) == 8);
+static_assert(sizeof(std::tuple<Overaligned>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal>) == 16);
+
+static_assert(sizeof(std::tuple<S, S>) == 2);
+static_assert(sizeof(std::tuple<Final, S>) == 1);
+static_assert(sizeof(std::tuple<NonEmpty, S>) == 8);
+static_assert(sizeof(std::tuple<NonEmptyFinal, S>) == 8);
+static_assert(sizeof(std::tuple<Overaligned, S>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal, S>) == 16);
+
+static_assert(sizeof(std::tuple<S, Final>) == 1);
+static_assert(sizeof(std::tuple<Final, Final>) == 2);
+static_assert(sizeof(std::tuple<NonEmpty, Final>) == 12);
+static_assert(sizeof(std::tuple<NonEmptyFinal, Final>) == 12);
+static_assert(sizeof(std::tuple<Overaligned, Final>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal, Final>) == 32);
+
+static_assert(sizeof(std::tuple<S, NonEmpty>) == 8);
+static_assert(sizeof(std::tuple<Final, NonEmpty>) == 12);
+static_assert(sizeof(std::tuple<NonEmpty, NonEmpty>) == 16);
+static_assert(sizeof(std::tuple<NonEmptyFinal, NonEmpty>) == 16);
+static_assert(sizeof(std::tuple<Overaligned, NonEmpty>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal, NonEmpty>) == 32);
+
+static_assert(sizeof(std::tuple<S, NonEmptyFinal>) == 8);
+static_assert(sizeof(std::tuple<Final, NonEmptyFinal>) == 12);
+static_assert(sizeof(std::tuple<NonEmpty, NonEmptyFinal>) == 16);
+static_assert(sizeof(std::tuple<NonEmptyFinal, NonEmptyFinal>) == 16);
+static_assert(sizeof(std::tuple<Overaligned, NonEmptyFinal>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal, NonEmptyFinal>) == 32);
+
+static_assert(sizeof(std::tuple<S, Overaligned>) == 16);
+static_assert(sizeof(std::tuple<Final, Overaligned>) == 16);
+static_assert(sizeof(std::tuple<NonEmpty, Overaligned>) == 16);
+static_assert(sizeof(std::tuple<NonEmptyFinal, Overaligned>) == 16);
+static_assert(sizeof(std::tuple<Overaligned, Overaligned>) == 32);
+static_assert(sizeof(std::tuple<OveralignedFinal, Overaligned>) == 16);
+
+static_assert(sizeof(std::tuple<S, OveralignedFinal>) == 16);
+static_assert(sizeof(std::tuple<Final, OveralignedFinal>) == 32);
+static_assert(sizeof(std::tuple<NonEmpty, OveralignedFinal>) == 32);
+static_assert(sizeof(std::tuple<NonEmptyFinal, OveralignedFinal>) == 32);
+static_assert(sizeof(std::tuple<Overaligned, OveralignedFinal>) == 16);
+static_assert(sizeof(std::tuple<OveralignedFinal, OveralignedFinal>) == 32);
More information about the libcxx-commits
mailing list