[libcxx-commits] [libcxx] [libc++] Add ABI tests for unordered_{map, set} (PR #107200)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 4 01:48:55 PDT 2024


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/107200

These are used to ensure #76756 is correct.


>From 79ff1c0708784de923a2f242466faf3010c40d22 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 4 Sep 2024 10:48:12 +0200
Subject: [PATCH] [libc++] Add ABI tests for unordered_{map,set}

---
 .../unord.map/abi.compile.pass.cpp            | 132 ++++++++++++++++++
 .../unord.set/abi.compile.pass.cpp            | 130 +++++++++++++++++
 2 files changed, 262 insertions(+)
 create mode 100644 libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/associative/unord.set/abi.compile.pass.cpp

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
new file mode 100644
index 00000000000000..00b238f14cd93a
--- /dev/null
+++ b/libcxx/test/libcxx/containers/associative/unord.map/abi.compile.pass.cpp
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdint>
+#include <unordered_map>
+
+#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::uint16_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; }
+};
+
+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; }
+};
+
+template <class T, class Alloc>
+using unordered_map_alloc = std::unordered_map<T, T, std::hash<T>, std::equal_to<T>, Alloc>;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
+
+static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
+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, AlignedHash, UnalignedEqualTo>) == 96);
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
+
+static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
+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, AlignedHash, UnalignedEqualTo>) == 96);
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#else
+#  error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx/containers/associative/unord.set/abi.compile.pass.cpp b/libcxx/test/libcxx/containers/associative/unord.set/abi.compile.pass.cpp
new file mode 100644
index 00000000000000..8eb173f90d9c9d
--- /dev/null
+++ b/libcxx/test/libcxx/containers/associative/unord.set/abi.compile.pass.cpp
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdint>
+#include <unordered_set>
+
+#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::uint16_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; }
+};
+
+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; }
+};
+
+template <class T, class Alloc>
+using unordered_map_alloc = std::unordered_set<T, std::hash<T>, std::equal_to<T>, Alloc>;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(unordered_map_alloc<int, std::allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, min_allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, test_allocator<int> >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(unordered_map_alloc<char, std::allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, min_allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, test_allocator<char> >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<int> >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<char> >) == 4, "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 96);
+static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(unordered_set_alloc<int, std::allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<int, min_allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<int, test_allocator<int> >) == 64, "");
+static_assert(sizeof(unordered_set_alloc<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(unordered_set_alloc<char, std::allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<char, min_allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<char, test_allocator<char> >) == 64, "");
+static_assert(sizeof(unordered_set_alloc<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, std::allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, small_iter_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, std::allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, small_iter_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 4, "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 96);
+static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#else
+#  error std::size_t has an unexpected size
+#endif



More information about the libcxx-commits mailing list