Skip to content

Commit 6cb339f

Browse files
authored
[libc++] Refactor tests for aligned allocation and sized deallocation (#117915)
This patch refactors the tests around aligned allocation and sized deallocation to avoid relying on passing the -fsized-deallocation or -faligned-allocation flags by default. Since both of these features are enabled by default in >= C++14 mode, it now makes sense to make that assumption in the test suite. A notable exception is MinGW and some older compilers, where sized deallocation is still not enabled by default. We treat that as a "bug" in the test suite and we work around it by explicitly adding -fsized-deallocation, but only under those configurations.
1 parent 5d9c321 commit 6cb339f

File tree

14 files changed

+147
-318
lines changed

14 files changed

+147
-318
lines changed

libcxx/test/benchmarks/allocation.bench.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// REQUIRES: -fsized-deallocation
10-
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation
9+
// UNSUPPORTED: c++03, c++11
10+
11+
// These compiler versions and platforms don't enable sized deallocation by default.
12+
// ADDITIONAL_COMPILE_FLAGS(clang-17): -fsized-deallocation
13+
// ADDITIONAL_COMPILE_FLAGS(clang-18): -fsized-deallocation
14+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-15): -fsized-deallocation
15+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-16): -fsized-deallocation
16+
// ADDITIONAL_COMPILE_FLAGS(target=x86_64-w64-windows-gnu): -fsized-deallocation
17+
// ADDITIONAL_COMPILE_FLAGS(target=i686-w64-windows-gnu): -fsized-deallocation
1118

1219
#include "benchmark/benchmark.h"
1320

libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp

Lines changed: 0 additions & 108 deletions
This file was deleted.

libcxx/test/libcxx/memory/shared_ptr_array.pass.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@
88
//
99

1010
// UNSUPPORTED: c++03, c++11, c++14, c++17
11-
// REQUIRES: -fsized-deallocation
12-
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation
11+
12+
// These compiler versions and platforms don't enable sized deallocation by default.
13+
// ADDITIONAL_COMPILE_FLAGS(clang-17): -fsized-deallocation
14+
// ADDITIONAL_COMPILE_FLAGS(clang-18): -fsized-deallocation
15+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-15): -fsized-deallocation
16+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-16): -fsized-deallocation
17+
// ADDITIONAL_COMPILE_FLAGS(target=x86_64-w64-windows-gnu): -fsized-deallocation
18+
// ADDITIONAL_COMPILE_FLAGS(target=i686-w64-windows-gnu): -fsized-deallocation
1319

1420
// This test will fail with ASan if the implementation passes different sizes
1521
// to corresponding allocation and deallocation functions.

libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,50 @@
1515
// XFAIL: target={{.+}}-zos{{.*}}
1616

1717
#include <new>
18+
#include <cassert>
19+
#include <cstddef>
20+
#include <string>
1821
#include <type_traits>
22+
#include <typeinfo>
1923

2024
#include "test_macros.h"
2125

22-
int main(int, char**) {
26+
constexpr bool test() {
27+
static_assert(std::is_enum<std::align_val_t>::value, "");
28+
static_assert(std::is_same<std::underlying_type<std::align_val_t>::type, std::size_t>::value, "");
29+
static_assert(!std::is_constructible<std::align_val_t, std::size_t>::value, "");
30+
static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
31+
2332
{
24-
static_assert(std::is_enum<std::align_val_t>::value, "");
25-
static_assert(std::is_same<std::underlying_type<std::align_val_t>::type, std::size_t>::value, "");
26-
static_assert(!std::is_constructible<std::align_val_t, std::size_t>::value, "");
27-
static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
33+
auto a = std::align_val_t(0);
34+
auto b = std::align_val_t(32);
35+
auto c = std::align_val_t(-1);
36+
assert(a != b);
37+
assert(a == std::align_val_t(0));
38+
assert(b == std::align_val_t(32));
39+
assert(static_cast<std::size_t>(c) == static_cast<std::size_t>(-1));
2840
}
41+
42+
return true;
43+
}
44+
45+
int main(int, char**) {
46+
test();
47+
static_assert(test(), "");
48+
49+
#if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_RTTI)
2950
{
30-
constexpr auto a = std::align_val_t(0);
31-
constexpr auto b = std::align_val_t(32);
32-
constexpr auto c = std::align_val_t(-1);
33-
static_assert(a != b, "");
34-
static_assert(a == std::align_val_t(0), "");
35-
static_assert(b == std::align_val_t(32), "");
36-
static_assert(static_cast<std::size_t>(c) == (std::size_t)-1, "");
51+
// Check that libc++ doesn't define align_val_t in a versioning namespace.
52+
// And that it mangles the same in C++03 through C++17
53+
# ifdef _MSC_VER
54+
// MSVC uses a different C++ ABI with a different name mangling scheme.
55+
// The type id name doesn't seem to contain the mangled form at all.
56+
assert(typeid(std::align_val_t).name() == std::string("enum std::align_val_t"));
57+
# else
58+
assert(typeid(std::align_val_t).name() == std::string("St11align_val_t"));
59+
# endif
3760
}
61+
#endif
3862

3963
return 0;
4064
}

libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@ void my_new_handler() {
3434
}
3535

3636
int main(int, char**) {
37-
// Test that we can call the function directly
38-
{
39-
void* x = operator new[](10, static_cast<std::align_val_t>(64));
37+
test_with_interesting_alignments([](std::size_t size, std::size_t alignment) {
38+
void* x = operator new[](size, static_cast<std::align_val_t>(alignment));
4039
assert(x != nullptr);
41-
assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
42-
operator delete[](x, static_cast<std::align_val_t>(64));
43-
}
40+
assert(reinterpret_cast<std::uintptr_t>(x) % alignment == 0);
41+
operator delete[](x, static_cast<std::align_val_t>(alignment));
42+
});
4443

4544
// Test that the new handler is called if allocation fails
4645
{

libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@ void my_new_handler() {
3434
}
3535

3636
int main(int, char**) {
37-
// Test that we can call the function directly
38-
{
39-
void* x = operator new[](10, static_cast<std::align_val_t>(64), std::nothrow);
37+
test_with_interesting_alignments([](std::size_t size, std::size_t alignment) {
38+
void* x = operator new[](size, static_cast<std::align_val_t>(alignment), std::nothrow);
4039
assert(x != nullptr);
41-
assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
42-
operator delete[](x, static_cast<std::align_val_t>(64), std::nothrow);
43-
}
40+
assert(reinterpret_cast<std::uintptr_t>(x) % alignment == 0);
41+
operator delete[](x, static_cast<std::align_val_t>(alignment), std::nothrow);
42+
});
4443

4544
// Test that the new handler is called and we return nullptr if allocation fails
4645
{
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,29 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// test sized operator delete[] replacement.
9+
// Test sized operator delete[] replacement.
1010

11-
// Note that sized delete operator definitions below are simply ignored
12-
// when sized deallocation is not supported, e.g., prior to C++14.
11+
// UNSUPPORTED: c++03, c++11
12+
13+
// These compiler versions and platforms don't enable sized deallocation by default.
14+
// ADDITIONAL_COMPILE_FLAGS(clang-17): -fsized-deallocation
15+
// ADDITIONAL_COMPILE_FLAGS(clang-18): -fsized-deallocation
16+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-15): -fsized-deallocation
17+
// ADDITIONAL_COMPILE_FLAGS(apple-clang-16): -fsized-deallocation
18+
// ADDITIONAL_COMPILE_FLAGS(target=x86_64-w64-windows-gnu): -fsized-deallocation
19+
// ADDITIONAL_COMPILE_FLAGS(target=i686-w64-windows-gnu): -fsized-deallocation
20+
21+
// Android clang-r536225 identifies as clang-19.0 but it predates the real
22+
// LLVM 19.0.0, so it also leaves sized deallocation off by default.
23+
// UNSUPPORTED: android && clang-19.0
1324

1425
// UNSUPPORTED: sanitizer-new-delete
1526

16-
// REQUIRES: -fsized-deallocation
17-
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation
27+
// Sized deallocation was introduced in LLVM 11
28+
// XFAIL: using-built-library-before-llvm-11
29+
30+
// AIX, and z/OS default to -fno-sized-deallocation.
31+
// XFAIL: target={{.+}}-aix{{.*}}, target={{.+}}-zos{{.*}}
1832

1933
#if !defined(__cpp_sized_deallocation)
2034
# error __cpp_sized_deallocation should be defined
@@ -76,5 +90,5 @@ int main(int, char**)
7690
assert(0 == unsized_delete_nothrow_called);
7791
assert(1 == sized_delete_called);
7892

79-
return 0;
93+
return 0;
8094
}

libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp

Lines changed: 0 additions & 78 deletions
This file was deleted.

libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@ void my_new_handler() {
3434
}
3535

3636
int main(int, char**) {
37-
// Test that we can call the function directly
38-
{
39-
void* x = operator new(10, static_cast<std::align_val_t>(64));
37+
test_with_interesting_alignments([](std::size_t size, std::size_t alignment) {
38+
void* x = operator new(size, static_cast<std::align_val_t>(alignment));
4039
assert(x != nullptr);
41-
assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
42-
operator delete(x, static_cast<std::align_val_t>(64));
43-
}
40+
assert(reinterpret_cast<std::uintptr_t>(x) % alignment == 0);
41+
operator delete(x, static_cast<std::align_val_t>(alignment));
42+
});
4443

4544
// Test that the new handler is called if allocation fails
4645
{

0 commit comments

Comments
 (0)