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

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 6 15:52:13 PST 2024


Author: Nikolas Klauser
Date: 2024-02-07T00:52:10+01:00
New Revision: 08457e1f7693bdafe5330cde2bf41290cad4cade

URL: https://github.com/llvm/llvm-project/commit/08457e1f7693bdafe5330cde2bf41290cad4cade
DIFF: https://github.com/llvm/llvm-project/commit/08457e1f7693bdafe5330cde2bf41290cad4cade.diff

LOG: [libc++] Add tests to pin down the ABI of deque, list and vector (#80191)

This patch adds tests that lock down the ABI of types like deque, list
and vector.
An upcoming patch will replace the usage of __compressed_pair in these
classes
by [[no_unique_address]], so we are adding these tests to pin down their
ABI
before making the change. That way, we can be confident that the patch
making
the actual ABI-sensitive change is safe if it doesn't break these tests.

Added: 
    libcxx/test/libcxx/containers/sequences/list/abi.compile.pass.cpp
    libcxx/test/libcxx/containers/sequences/vector.bool/abi.compile.pass.cpp
    libcxx/test/libcxx/containers/sequences/vector/abi.compile.pass.cpp

Modified: 
    libcxx/test/libcxx/containers/sequences/deque/abi.compile.pass.cpp

Removed: 
    


################################################################################
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 
diff erence_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 
diff erence_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 
diff erence_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 
diff erence_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 
diff erence_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