diff options
author | Nikolas Klauser <nikolasklauser@berlin.de> | 2024-02-07 00:52:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-07 00:52:10 +0100 |
commit | 08457e1f7693bdafe5330cde2bf41290cad4cade (patch) | |
tree | 6366434c8f3d4017b89bf6b93d1868d4bb0dd890 /libcxx | |
parent | fbded6663fb04d12f451c18bc8018989d2db3a87 (diff) | |
download | llvm-08457e1f7693bdafe5330cde2bf41290cad4cade.zip llvm-08457e1f7693bdafe5330cde2bf41290cad4cade.tar.gz llvm-08457e1f7693bdafe5330cde2bf41290cad4cade.tar.bz2 |
[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.
Diffstat (limited to 'libcxx')
4 files changed, 267 insertions, 1 deletions
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 37e87d5..9910bef 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 @@ public: 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 0000000..8ace45d --- /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 0000000..48337a0c --- /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 0000000..b03f484 --- /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 |