[libcxx-commits] [libcxx] [libc++] Add tests to pin down the ABI of deque, list and vector (PR #80191)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 6 06:56:07 PST 2024


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/80191

>From 4785bd026a412b3020495175874fec634f671fb6 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 31 Jan 2024 21:25:26 +0100
Subject: [PATCH] [libc++] Add tests for the ABI of deque, list and vector for
 replacing __compressed_pair with [[no_unique_address]]

---
 .../sequences/deque/abi.compile.pass.cpp      | 30 ++++++-
 .../sequences/list/abi.compile.pass.cpp       | 86 +++++++++++++++++++
 .../vector.bool/abi.compile.pass.cpp          | 66 ++++++++++++++
 .../sequences/vector/abi.compile.pass.cpp     | 86 +++++++++++++++++++
 4 files changed, 267 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/test/libcxx/containers/sequences/list/abi.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/vector.bool/abi.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/vector/abi.compile.pass.cpp

diff --git a/libcxx/test/libcxx/containers/sequences/deque/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/deque/abi.compile.pass.cpp
index 37e87d59503ee..9910befb0349e 100644
--- a/libcxx/test/libcxx/containers/sequences/deque/abi.compile.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/deque/abi.compile.pass.cpp
@@ -22,7 +22,7 @@ class small_iter_allocator {
 public:
   using value_type      = T;
   using pointer         = small_pointer<T>;
-  using size_type       = std::int16_t;
+  using size_type       = std::uint16_t;
   using difference_type = std::int16_t;
 
   small_iter_allocator() TEST_NOEXCEPT {}
@@ -37,27 +37,51 @@ class small_iter_allocator {
   friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
 };
 
+template <class T>
+class final_small_iter_allocator final {
+public:
+  using value_type      = T;
+  using pointer         = small_pointer<T>;
+  using size_type       = std::uint16_t;
+  using difference_type = std::int16_t;
+
+  final_small_iter_allocator() TEST_NOEXCEPT {}
+
+  template <class U>
+  final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+  T* allocate(std::size_t n);
+  void deallocate(T* p, std::size_t);
+
+  friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
+  friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
+};
+
 #if __SIZE_WIDTH__ == 64
 
 static_assert(sizeof(std::deque<int>) == 48, "");
 static_assert(sizeof(std::deque<int, min_allocator<int> >) == 48, "");
 static_assert(sizeof(std::deque<int, test_allocator<int> >) == 80, "");
 static_assert(sizeof(std::deque<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(std::deque<int, final_small_iter_allocator<int> >) == 16, "");
 
 static_assert(sizeof(std::deque<char>) == 48, "");
 static_assert(sizeof(std::deque<char, min_allocator<char> >) == 48, "");
 static_assert(sizeof(std::deque<char, test_allocator<char> >) == 80, "");
 static_assert(sizeof(std::deque<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(std::deque<char, final_small_iter_allocator<char> >) == 16, "");
 
 static_assert(TEST_ALIGNOF(std::deque<int>) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<int, min_allocator<int> >) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<int, test_allocator<int> >) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<int, small_iter_allocator<int> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<int, final_small_iter_allocator<int> >) == 2, "");
 
 static_assert(TEST_ALIGNOF(std::deque<char>) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<char, min_allocator<char> >) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<char, test_allocator<char> >) == 8, "");
 static_assert(TEST_ALIGNOF(std::deque<char, small_iter_allocator<char> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<char, final_small_iter_allocator<char> >) == 2, "");
 
 #elif __SIZE_WIDTH__ == 32
 
@@ -65,21 +89,25 @@ static_assert(sizeof(std::deque<int>) == 24, "");
 static_assert(sizeof(std::deque<int, min_allocator<int> >) == 24, "");
 static_assert(sizeof(std::deque<int, test_allocator<int> >) == 48, "");
 static_assert(sizeof(std::deque<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(std::deque<int, final_small_iter_allocator<int> >) == 16, "");
 
 static_assert(sizeof(std::deque<char>) == 24, "");
 static_assert(sizeof(std::deque<char, min_allocator<char> >) == 24, "");
 static_assert(sizeof(std::deque<char, test_allocator<char> >) == 48, "");
 static_assert(sizeof(std::deque<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(std::deque<char, final_small_iter_allocator<char> >) == 16, "");
 
 static_assert(TEST_ALIGNOF(std::deque<int>) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<int, min_allocator<int> >) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<int, test_allocator<int> >) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<int, small_iter_allocator<int> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<int, final_small_iter_allocator<int> >) == 2, "");
 
 static_assert(TEST_ALIGNOF(std::deque<char>) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<char, min_allocator<char> >) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<char, test_allocator<char> >) == 4, "");
 static_assert(TEST_ALIGNOF(std::deque<char, small_iter_allocator<char> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<char, final_small_iter_allocator<char> >) == 2, "");
 
 #else
 #  error std::size_t has an unexpected size
diff --git a/libcxx/test/libcxx/containers/sequences/list/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/list/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..8ace45d661df6
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/list/abi.compile.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <list>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+  std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+  using value_type      = T;
+  using pointer         = small_pointer<T>;
+  using size_type       = std::int16_t;
+  using difference_type = std::int16_t;
+
+  small_iter_allocator() TEST_NOEXCEPT {}
+
+  template <class U>
+  small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+  T* allocate(std::size_t n);
+  void deallocate(T* p, std::size_t);
+
+  friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+  friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::list<int>) == 24, "");
+static_assert(sizeof(std::list<int, min_allocator<int> >) == 24, "");
+static_assert(sizeof(std::list<int, test_allocator<int> >) == 40, "");
+static_assert(sizeof(std::list<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::list<char>) == 24, "");
+static_assert(sizeof(std::list<char, min_allocator<char> >) == 24, "");
+static_assert(sizeof(std::list<char, test_allocator<char> >) == 40, "");
+static_assert(sizeof(std::list<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::list<int>) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::list<char>) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, small_iter_allocator<char> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::list<int>) == 12, "");
+static_assert(sizeof(std::list<int, min_allocator<int> >) == 12, "");
+static_assert(sizeof(std::list<int, test_allocator<int> >) == 24, "");
+static_assert(sizeof(std::list<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::list<char>) == 12, "");
+static_assert(sizeof(std::list<char, min_allocator<char> >) == 12, "");
+static_assert(sizeof(std::list<char, test_allocator<char> >) == 24, "");
+static_assert(sizeof(std::list<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::list<int>) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::list<char>) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, small_iter_allocator<char> >) == 2, "");
+
+#else
+#  error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx/containers/sequences/vector.bool/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector.bool/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..48337a0c5cc1b
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector.bool/abi.compile.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+  std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+  using value_type      = T;
+  using pointer         = small_pointer<T>;
+  using size_type       = std::int16_t;
+  using difference_type = std::int16_t;
+
+  small_iter_allocator() TEST_NOEXCEPT {}
+
+  template <class U>
+  small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+  T* allocate(std::size_t n);
+  void deallocate(T* p, std::size_t);
+
+  friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+  friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::vector<bool>) == 24, "");
+static_assert(sizeof(std::vector<bool, min_allocator<bool> >) == 24, "");
+static_assert(sizeof(std::vector<bool, test_allocator<bool> >) == 40, "");
+static_assert(sizeof(std::vector<bool, small_iter_allocator<bool> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<bool>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, min_allocator<bool> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, test_allocator<bool> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, small_iter_allocator<bool> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::vector<bool>) == 12, "");
+static_assert(sizeof(std::vector<bool, min_allocator<bool> >) == 12, "");
+static_assert(sizeof(std::vector<bool, test_allocator<bool> >) == 24, "");
+static_assert(sizeof(std::vector<bool, small_iter_allocator<bool> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<bool>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, min_allocator<bool> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, test_allocator<bool> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, small_iter_allocator<bool> >) == 2, "");
+
+#else
+#  error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx/containers/sequences/vector/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..b03f48434a0e0
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector/abi.compile.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+  std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+  using value_type      = T;
+  using pointer         = small_pointer<T>;
+  using size_type       = std::int16_t;
+  using difference_type = std::int16_t;
+
+  small_iter_allocator() TEST_NOEXCEPT {}
+
+  template <class U>
+  small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+  T* allocate(std::size_t n);
+  void deallocate(T* p, std::size_t);
+
+  friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+  friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::vector<int>) == 24, "");
+static_assert(sizeof(std::vector<int, min_allocator<int> >) == 24, "");
+static_assert(sizeof(std::vector<int, test_allocator<int> >) == 40, "");
+static_assert(sizeof(std::vector<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::vector<char>) == 24, "");
+static_assert(sizeof(std::vector<char, min_allocator<char> >) == 24, "");
+static_assert(sizeof(std::vector<char, test_allocator<char> >) == 40, "");
+static_assert(sizeof(std::vector<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<int>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::vector<char>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, small_iter_allocator<char> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::vector<int>) == 12, "");
+static_assert(sizeof(std::vector<int, min_allocator<int> >) == 12, "");
+static_assert(sizeof(std::vector<int, test_allocator<int> >) == 24, "");
+static_assert(sizeof(std::vector<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::vector<char>) == 12, "");
+static_assert(sizeof(std::vector<char, min_allocator<char> >) == 12, "");
+static_assert(sizeof(std::vector<char, test_allocator<char> >) == 24, "");
+static_assert(sizeof(std::vector<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<int>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::vector<char>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, small_iter_allocator<char> >) == 2, "");
+
+#else
+#  error std::size_t has an unexpected size
+#endif



More information about the libcxx-commits mailing list