diff options
Diffstat (limited to 'libcxx/test')
28 files changed, 504 insertions, 100 deletions
diff --git a/libcxx/test/benchmarks/bitset.bench.cpp b/libcxx/test/benchmarks/bitset.bench.cpp index 8fcf52e..b4c7e6f 100644 --- a/libcxx/test/benchmarks/bitset.bench.cpp +++ b/libcxx/test/benchmarks/bitset.bench.cpp @@ -103,7 +103,7 @@ BENCHMARK(BM_BitsetToString<262144>)->Arg(50)->Name("BM_BitsetToString<262144>/U BENCHMARK(BM_BitsetToString<524288>)->Arg(50)->Name("BM_BitsetToString<524288>/Uniform (50%)"); BENCHMARK(BM_BitsetToString<1048576>)->Arg(50)->Name("BM_BitsetToString<1048576>/Uniform (50%)"); // 1 << 20 -static void BM_ctor_ull(benchmark::State& state) { +static void BM_Bitset_ctor_ull(benchmark::State& state) { unsigned long long val = (1ULL << state.range(0)) - 1; for (auto _ : state) { std::bitset<128> b(val); @@ -111,6 +111,6 @@ static void BM_ctor_ull(benchmark::State& state) { } } -BENCHMARK(BM_ctor_ull)->DenseRange(1, 63); +BENCHMARK(BM_Bitset_ctor_ull)->DenseRange(1, 63); BENCHMARK_MAIN(); diff --git a/libcxx/test/benchmarks/iterators/distance.bench.cpp b/libcxx/test/benchmarks/iterators/distance.bench.cpp new file mode 100644 index 0000000..186ef79 --- /dev/null +++ b/libcxx/test/benchmarks/iterators/distance.bench.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <algorithm> +#include <cstddef> +#include <deque> +#include <iterator> +#include <ranges> +#include <vector> + +#include <benchmark/benchmark.h> + +int main(int argc, char** argv) { + auto std_distance = [](auto first, auto last) { return std::distance(first, last); }; + + // {std,ranges}::distance(std::deque) + { + auto bm = [](std::string name, auto distance) { + benchmark::RegisterBenchmark( + name, + [distance](auto& st) { + std::size_t const size = st.range(0); + std::deque<int> c(size, 1); + + for ([[maybe_unused]] auto _ : st) { + benchmark::DoNotOptimize(c); + auto result = distance(c.begin(), c.end()); + benchmark::DoNotOptimize(result); + } + }) + ->Arg(50) // non power-of-two + ->Arg(1024) + ->Arg(4096) + ->Arg(8192); + }; + bm.operator()("std::distance(deque<int>)", std_distance); + bm.operator()("rng::distance(deque<int>)", std::ranges::distance); + } + + // {std,ranges}::distance(std::join_view) + { + auto bm = []<class Container>(std::string name, auto distance, std::size_t seg_size) { + benchmark::RegisterBenchmark( + name, + [distance, seg_size](auto& st) { + std::size_t const size = st.range(0); + std::size_t const segments = (size + seg_size - 1) / seg_size; + Container c(segments); + for (std::size_t i = 0, n = size; i < segments; ++i, n -= seg_size) { + c[i].resize(std::min(seg_size, n)); + } + + auto view = c | std::views::join; + auto first = view.begin(); + auto last = view.end(); + + for ([[maybe_unused]] auto _ : st) { + benchmark::DoNotOptimize(c); + auto result = distance(first, last); + benchmark::DoNotOptimize(result); + } + }) + ->Arg(50) // non power-of-two + ->Arg(1024) + ->Arg(4096) + ->Arg(8192); + }; + bm.operator()<std::vector<std::vector<int>>>("std::distance(join_view(vector<vector<int>>))", std_distance, 256); + bm.operator()<std::vector<std::vector<int>>>( + "rng::distance(join_view(vector<vector<int>>)", std::ranges::distance, 256); + } + + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); + benchmark::Shutdown(); + return 0; +} diff --git a/libcxx/test/benchmarks/utility/cmp.bench.cpp b/libcxx/test/benchmarks/utility/cmp.bench.cpp new file mode 100644 index 0000000..1ed179a --- /dev/null +++ b/libcxx/test/benchmarks/utility/cmp.bench.cpp @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <utility> +#include "../CartesianBenchmarks.h" +#include "benchmark/benchmark.h" + +namespace { + +enum ValueType : size_t { + SChar, + UChar, + Short, + UShort, + Int, + UInt, + Long, + ULong, + LongLong, + ULongLong, +#ifndef TEST_HAS_NO_INT128 + Int128, + UInt128, +#endif +}; + +struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 6> { + static constexpr const char* Names[] = { + "schar", + "uchar", + "short", + "ushort", + "int", + "uint", + "long", + "ulong", + "longlong", + "ulonglong", +#ifndef TEST_HAS_NO_INT128 + "int128", + "uint128" +#endif + }; +}; + +using TestType = + std::tuple< signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long +#ifndef TEST_HAS_NO_INT128 + , + __int128_t, + __uint128_t +#endif + >; + +template <typename TType, typename UType> +struct CmpEqual { + static void run(benchmark::State& state) { + using T = std::tuple_element_t<TType::value, TestType>; + using U = std::tuple_element_t<UType::value, TestType>; + + T x1 = T{127}, x2 = T{111}; + U y1 = U{123}, y2 = U{1}; + for (auto _ : state) { + benchmark::DoNotOptimize(x1); + benchmark::DoNotOptimize(x2); + benchmark::DoNotOptimize(y1); + benchmark::DoNotOptimize(y2); + benchmark::DoNotOptimize(std::cmp_equal(x1, y1)); + benchmark::DoNotOptimize(std::cmp_equal(y1, x1)); + benchmark::DoNotOptimize(std::cmp_equal(x1, x1)); + benchmark::DoNotOptimize(std::cmp_equal(y1, y1)); + + benchmark::DoNotOptimize(std::cmp_equal(x2, y2)); + benchmark::DoNotOptimize(std::cmp_equal(y2, x2)); + benchmark::DoNotOptimize(std::cmp_equal(x2, x2)); + benchmark::DoNotOptimize(std::cmp_equal(y2, y2)); + } + } + + static std::string name() { return "BM_CmpEqual" + TType::name() + UType::name(); } +}; + +template <typename TType, typename UType> +struct CmpLess { + static void run(benchmark::State& state) { + using T = std::tuple_element_t<TType::value, TestType>; + using U = std::tuple_element_t<UType::value, TestType>; + + T x1 = T{127}, x2 = T{111}; + U y1 = U{123}, y2 = U{1}; + for (auto _ : state) { + benchmark::DoNotOptimize(x1); + benchmark::DoNotOptimize(x2); + benchmark::DoNotOptimize(y1); + benchmark::DoNotOptimize(y2); + benchmark::DoNotOptimize(std::cmp_less(x1, y1)); + benchmark::DoNotOptimize(std::cmp_less(y1, x1)); + benchmark::DoNotOptimize(std::cmp_less(x1, x1)); + benchmark::DoNotOptimize(std::cmp_less(y1, y1)); + + benchmark::DoNotOptimize(std::cmp_less(x2, y2)); + benchmark::DoNotOptimize(std::cmp_less(y2, x2)); + benchmark::DoNotOptimize(std::cmp_less(x2, x2)); + benchmark::DoNotOptimize(std::cmp_less(y2, y2)); + } + } + + static std::string name() { return "BM_CmpLess" + TType::name() + UType::name(); } +}; + +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + makeCartesianProductBenchmark<CmpEqual, AllValueTypes, AllValueTypes>(); + makeCartesianProductBenchmark<CmpLess, AllValueTypes, AllValueTypes>(); + benchmark::RunSpecifiedBenchmarks(); + + return 0; +} diff --git a/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp b/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp index 390c6b6..3c7a2d4 100644 --- a/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp +++ b/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp @@ -12,9 +12,7 @@ // failures when back-deploying. // XFAIL: availability-verbose_abort-missing -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - -#include <__verbose_abort> +#include <__cxx03/__verbose_abort> #include <cstdlib> void std::__libcpp_verbose_abort(char const*, ...) _NOEXCEPT { std::exit(EXIT_SUCCESS); } diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp index 320ef57..1bd5792 100644 --- a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp +++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // <atomic> // template <class T> @@ -48,12 +46,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add(&fun, 0); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add(&fun, 0); } } diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp index bdd8089..bdd4a83 100644 --- a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp +++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // <atomic> // template <class T> @@ -51,12 +49,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp index 2c9f898..105a010 100644 --- a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp +++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // <atomic> // template <class T> @@ -48,12 +46,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub(&fun, 0); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub(&fun, 0); } } diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp index 88c4275..1647ed3 100644 --- a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp +++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // <atomic> // template <class T> @@ -51,12 +49,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp index 2b6c380..d6caa33 100644 --- a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp +++ b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp @@ -8,8 +8,6 @@ // <sstream> -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // How the constructors of basic_stringbuf initialize the buffer pointers is // not specified. For some constructors it's implementation defined whether the // pointers are set to nullptr. Libc++'s implementation directly uses the SSO diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 7ead65c..a9fe04f 100644 --- a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -21,8 +21,6 @@ // GCC doesn't support the aligned-allocation flags. // XFAIL: gcc -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // RUN: %{build} -faligned-allocation -fsized-deallocation // RUN: %{run} // RUN: %{build} -faligned-allocation -fno-sized-deallocation -DNO_SIZE @@ -40,7 +38,7 @@ TEST_DIAGNOSTIC_PUSH TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header") -#include <__memory/aligned_alloc.h> +#include <__cxx03/__memory/aligned_alloc.h> TEST_DIAGNOSTIC_POP struct alloc_stats { @@ -138,42 +136,42 @@ void test_libcpp_dealloc() { std::size_t with_size_val = 2; { - std::__libcpp_deallocate_unsized<char>(static_cast<char*>(p), under_align_val); + std::__libcpp_deallocate_unsized(p, under_align_val); assert(stats.expect_plain()); } stats.reset(); #if defined(NO_SIZE) && defined(NO_ALIGN) { - std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val); + std::__libcpp_deallocate(p, with_size_val, over_align_val); assert(stats.expect_plain()); } stats.reset(); #elif defined(NO_SIZE) { - std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val); + std::__libcpp_deallocate(p, with_size_val, over_align_val); assert(stats.expect_align(over_align_val)); } stats.reset(); #elif defined(NO_ALIGN) { - std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val); + std::__libcpp_deallocate(p, with_size_val, over_align_val); assert(stats.expect_size(with_size_val)); } stats.reset(); #else { - std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val); + std::__libcpp_deallocate(p, with_size_val, over_align_val); assert(stats.expect_size_align(with_size_val, over_align_val)); } stats.reset(); { - std::__libcpp_deallocate_unsized<char>(static_cast<char*>(p), over_align_val); + std::__libcpp_deallocate_unsized(p, over_align_val); assert(stats.expect_align(over_align_val)); } stats.reset(); { - std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), under_align_val); + std::__libcpp_deallocate(p, with_size_val, under_align_val); assert(stats.expect_size(with_size_val)); } stats.reset(); diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp index fcbf649..283adbc 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp @@ -15,8 +15,6 @@ // UNSUPPORTED: no-wide-characters -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <fstream> std::basic_filebuf<char, std::char_traits<wchar_t> > f; diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp index 8eca76c..ba6f3c3 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp @@ -15,8 +15,6 @@ // UNSUPPORTED: no-wide-characters -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <fstream> std::basic_fstream<char, std::char_traits<wchar_t> > f; diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp index 3c9cf9b..bede567 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp @@ -12,8 +12,6 @@ // constexpr OutIter // constexpr after C++17 // copy(InIter first, InIter last, OutIter result); -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <algorithm> #include <cassert> #include <vector> diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp index 9b403db..b0a74b8 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp @@ -17,6 +17,8 @@ #include <array> #include <cassert> #include <cstddef> +#include <deque> +#include <ranges> #include <vector> #include "sized_allocator.h" @@ -93,6 +95,13 @@ TEST_CONSTEXPR_CXX20 bool test_vector_bool(std::size_t N) { return true; } +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + std::deque<int> in(20); + std::deque<int> expected(in.size(), 42); + std::fill(in.begin(), in.end(), 42); + assert(in == expected); +} + TEST_CONSTEXPR_CXX20 bool test() { types::for_each(types::forward_iterator_list<char*>(), Test<char>()); types::for_each(types::forward_iterator_list<int*>(), Test<int>()); @@ -138,6 +147,20 @@ TEST_CONSTEXPR_CXX20 bool test() { } } + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); + +#if TEST_STD_VER >= 20 + { // Verify that join_view of vectors work properly. + std::vector<std::vector<int>> v{{1, 2}, {1, 2, 3}, {}, {3, 4, 5}, {6}, {7, 8, 9, 6}, {0, 1, 2, 3, 0, 1, 2}}; + auto jv = std::ranges::join_view(v); + std::fill(jv.begin(), jv.end(), 42); + for (const auto& vec : v) + for (auto n : vec) + assert(n == 42); + } +#endif + return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp index e42172c..5dc9b90 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp @@ -17,6 +17,8 @@ #include <array> #include <cassert> #include <cstddef> +#include <deque> +#include <ranges> #include <vector> #include "sized_allocator.h" @@ -126,6 +128,13 @@ TEST_CONSTEXPR_CXX20 bool test_vector_bool(std::size_t N) { return true; } +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + std::deque<int> in(20); + std::deque<int> expected(in.size(), 42); + std::fill_n(in.begin(), in.size(), 42); + assert(in == expected); +} + TEST_CONSTEXPR_CXX20 bool test() { types::for_each(types::forward_iterator_list<char*>(), Test<char>()); types::for_each(types::forward_iterator_list<int*>(), Test<int>()); @@ -221,6 +230,20 @@ TEST_CONSTEXPR_CXX20 bool test() { } } + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); + +#if TEST_STD_VER >= 20 + { + std::vector<std::vector<int>> v{{1, 2}, {1, 2, 3}, {}, {3, 4, 5}, {6}, {7, 8, 9, 6}, {0, 1, 2, 3, 0, 1, 2}}; + auto jv = std::ranges::join_view(v); + std::fill_n(jv.begin(), std::distance(jv.begin(), jv.end()), 42); + for (const auto& vec : v) + for (auto n : vec) + assert(n == 42); + } +#endif + return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp index 61a659f..7ae0a06 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp @@ -18,6 +18,7 @@ #include <algorithm> #include <array> #include <cassert> +#include <deque> #include <ranges> #include <string> #include <vector> @@ -128,6 +129,13 @@ constexpr bool test_vector_bool(std::size_t N) { } #endif +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + std::deque<int> in(20); + std::deque<int> expected(in.size(), 42); + std::ranges::fill(in, 42); + assert(in == expected); +} + constexpr bool test() { test_iterators<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>(); test_iterators<cpp20_output_iterator<int*>, sentinel_wrapper<cpp20_output_iterator<int*>>>(); @@ -227,6 +235,20 @@ constexpr bool test() { } #endif + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); + +#if TEST_STD_VER >= 20 + { + std::vector<std::vector<int>> v{{1, 2}, {1, 2, 3}, {}, {3, 4, 5}, {6}, {7, 8, 9, 6}, {0, 1, 2, 3, 0, 1, 2}}; + auto jv = std::ranges::join_view(v); + std::ranges::fill(jv, 42); + for (const auto& vec : v) + for (auto n : vec) + assert(n == 42); + } +#endif + return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp index 2d6e24a..25db892 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <array> #include <cassert> +#include <deque> #include <ranges> #include <string> #include <vector> @@ -101,6 +102,13 @@ constexpr bool test_vector_bool(std::size_t N) { } #endif +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + std::deque<int> in(20); + std::deque<int> expected(in.size(), 42); + std::ranges::fill_n(std::ranges::begin(in), std::ranges::size(in), 42); + assert(in == expected); +} + constexpr bool test() { test_iterators<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>(); test_iterators<cpp20_output_iterator<int*>, sentinel_wrapper<cpp20_output_iterator<int*>>>(); @@ -175,6 +183,20 @@ constexpr bool test() { } #endif + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); + +#if TEST_STD_VER >= 20 + { + std::vector<std::vector<int>> v{{1, 2}, {1, 2, 3}, {}, {3, 4, 5}, {6}, {7, 8, 9, 6}, {0, 1, 2, 3, 0, 1, 2}}; + auto jv = std::ranges::join_view(v); + std::ranges::fill_n(std::ranges::begin(jv), std::ranges::distance(jv), 42); + for (const auto& vec : v) + for (auto n : vec) + assert(n == 42); + } +#endif + return true; } diff --git a/libcxx/test/std/atomics/types.pass.cpp b/libcxx/test/std/atomics/types.pass.cpp index c979392..b1edec5 100644 --- a/libcxx/test/std/atomics/types.pass.cpp +++ b/libcxx/test/std/atomics/types.pass.cpp @@ -17,9 +17,6 @@ // typedef T value_type; // }; -// atomic still has a difference_type in the C++03 frozen headers -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <atomic> #include <chrono> #include <cstdint> diff --git a/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp index 665867a..bf17733 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp @@ -11,8 +11,6 @@ // void shrink_to_fit(); -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <cassert> #include <climits> #include <vector> diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp index 00de053..679eec2 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp @@ -11,8 +11,6 @@ // (bug report: https://llvm.org/PR58392) // Check that vector constructors don't leak memory when an operation inside the constructor throws an exception -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <cstddef> #include <memory> #include <type_traits> diff --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp index dac4396..d131f5c 100644 --- a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp @@ -15,8 +15,6 @@ // basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} // C++20 // explicit basic_stringbuf(ios_base::openmode which); // C++20 -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <sstream> #include <cassert> diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.operations/distance.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.operations/distance.pass.cpp index 13caeff..d92a44f 100644 --- a/libcxx/test/std/iterators/iterator.primitives/iterator.operations/distance.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.operations/distance.pass.cpp @@ -16,38 +16,73 @@ // Iter::difference_type // distance(Iter first, Iter last); // constexpr in C++17 -#include <iterator> +#include <array> #include <cassert> +#include <deque> +#include <iterator> +#include <vector> #include <type_traits> #include "test_macros.h" #include "test_iterators.h" template <class It> -TEST_CONSTEXPR_CXX17 -void check_distance(It first, It last, typename std::iterator_traits<It>::difference_type dist) -{ - typedef typename std::iterator_traits<It>::difference_type Difference; - static_assert(std::is_same<decltype(std::distance(first, last)), Difference>::value, ""); - assert(std::distance(first, last) == dist); +TEST_CONSTEXPR_CXX17 void check_distance(It first, It last, typename std::iterator_traits<It>::difference_type dist) { + typedef typename std::iterator_traits<It>::difference_type Difference; + static_assert(std::is_same<decltype(std::distance(first, last)), Difference>::value, ""); + assert(std::distance(first, last) == dist); } -TEST_CONSTEXPR_CXX17 bool tests() -{ - const char* s = "1234567890"; - check_distance(cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), 10); - check_distance(forward_iterator<const char*>(s), forward_iterator<const char*>(s+10), 10); - check_distance(bidirectional_iterator<const char*>(s), bidirectional_iterator<const char*>(s+10), 10); - check_distance(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+10), 10); - check_distance(s, s+10, 10); - return true; +#if TEST_STD_VER >= 20 +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + using Container = std::deque<std::deque<double>>; + Container c; + auto view = c | std::views::join; + Container::difference_type n = 0; + for (std::size_t i = 0; i < 10; ++i) { + n += i; + c.push_back(Container::value_type(i)); + } + assert(std::distance(view.begin(), view.end()) == n); +} +#endif + +TEST_CONSTEXPR_CXX17 bool tests() { + const char* s = "1234567890"; + check_distance(cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 10), 10); + check_distance(forward_iterator<const char*>(s), forward_iterator<const char*>(s + 10), 10); + check_distance(bidirectional_iterator<const char*>(s), bidirectional_iterator<const char*>(s + 10), 10); + check_distance(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s + 10), 10); + check_distance(s, s + 10, 10); + +#if TEST_STD_VER >= 20 + { + using Container = std::vector<std::vector<int>>; + Container c; + auto view = c | std::views::join; + Container::difference_type n = 0; + for (std::size_t i = 0; i < 10; ++i) { + n += i; + c.push_back(Container::value_type(i)); + } + assert(std::distance(view.begin(), view.end()) == n); + } + { + using Container = std::array<std::array<char, 3>, 10>; + Container c; + auto view = c | std::views::join; + assert(std::distance(view.begin(), view.end()) == 30); + } + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); +#endif + return true; } -int main(int, char**) -{ - tests(); +int main(int, char**) { + tests(); #if TEST_STD_VER >= 17 - static_assert(tests(), ""); + static_assert(tests(), ""); #endif - return 0; + return 0; } diff --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp index b4199b7..1b78489 100644 --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp @@ -15,18 +15,21 @@ // template<class I, sized_sentinel_for<decay_t<I>> S> // constexpr iter_difference_t<I> ranges::distance(I&& first, S last); // TODO: update when LWG3664 is resolved -#include <iterator> +#include <array> #include <cassert> +#include <deque> +#include <iterator> +#include <vector> #include "test_iterators.h" #include "test_macros.h" -template<class It, class Sent> +template <class It, class Sent> constexpr void test_unsized() { static_assert(std::sentinel_for<Sent, It> && !std::sized_sentinel_for<Sent, It>); - int a[3] = {1,2,3}; + int a[3] = {1, 2, 3}; { - It first = It(a); + It first = It(a); auto last = Sent(It(a)); assert(std::ranges::distance(first, last) == 0); assert(std::ranges::distance(It(a), last) == 0); @@ -36,7 +39,7 @@ constexpr void test_unsized() { } { auto check = [&a]<class ItQual, class SentQual> { - It first = It(a); + It first = It(a); Sent last = Sent(It(a + 3)); assert(std::ranges::distance(static_cast<ItQual>(first), static_cast<SentQual>(last)) == 3); }; @@ -61,13 +64,13 @@ constexpr void test_unsized() { } } -template<class It, class Sent> +template <class It, class Sent> constexpr void test_sized() { static_assert(std::sized_sentinel_for<Sent, It>); - int a[] = {1,2,3}; + int a[] = {1, 2, 3}; { auto check = [&a]<class ItQual, class SentQual> { - It first = It(a + 3); + It first = It(a + 3); Sent last = Sent(It(a)); assert(std::ranges::distance(static_cast<ItQual>(first), static_cast<SentQual>(last)) == -3); }; @@ -91,7 +94,7 @@ constexpr void test_sized() { check.template operator()<const It&&, const Sent&&>(); } { - It first = It(a); + It first = It(a); auto last = Sent(It(a)); assert(std::ranges::distance(first, last) == 0); assert(std::ranges::distance(It(a), last) == 0); @@ -100,7 +103,7 @@ constexpr void test_sized() { ASSERT_SAME_TYPE(decltype(std::ranges::distance(It(a), Sent(It(a)))), std::iter_difference_t<It>); } { - It first = It(a); + It first = It(a); auto last = Sent(It(a + 3)); assert(std::ranges::distance(first, last) == 3); assert(std::ranges::distance(It(a), last) == 3); @@ -110,13 +113,17 @@ constexpr void test_sized() { } struct StrideCounter { - int *it_; - int *inc_; - using value_type = int; + int* it_; + int* inc_; + using value_type = int; using difference_type = int; explicit StrideCounter(); - constexpr explicit StrideCounter(int *it, int *inc) : it_(it), inc_(inc) {} - constexpr auto& operator++() { ++it_; *inc_ += 1; return *this; } + constexpr explicit StrideCounter(int* it, int* inc) : it_(it), inc_(inc) {} + constexpr auto& operator++() { + ++it_; + *inc_ += 1; + return *this; + } StrideCounter operator++(int); int& operator*() const; bool operator==(StrideCounter) const; @@ -125,11 +132,11 @@ static_assert(std::forward_iterator<StrideCounter>); static_assert(!std::sized_sentinel_for<StrideCounter, StrideCounter>); struct SizedStrideCounter { - int *it_; - int *minus_; + int* it_; + int* minus_; using value_type = int; explicit SizedStrideCounter(); - constexpr explicit SizedStrideCounter(int *it, int *minus) : it_(it), minus_(minus) {} + constexpr explicit SizedStrideCounter(int* it, int* minus) : it_(it), minus_(minus) {} SizedStrideCounter& operator++(); SizedStrideCounter operator++(int); int& operator*() const; @@ -147,22 +154,34 @@ constexpr void test_stride_counting() { int a[] = {1, 2, 3}; int inc = 0; StrideCounter first(a, &inc); - StrideCounter last(a+3, nullptr); + StrideCounter last(a + 3, nullptr); std::same_as<int> auto result = std::ranges::distance(first, last); assert(result == 3); assert(inc == 3); } { - int a[] = {1, 2, 3}; + int a[] = {1, 2, 3}; int minus = 0; SizedStrideCounter first(a, &minus); - SizedStrideCounter last(a+3, nullptr); + SizedStrideCounter last(a + 3, nullptr); std::same_as<int> auto result = std::ranges::distance(first, last); assert(result == 3); assert(minus == 1); } } +/*TEST_CONSTEXPR_CXX26*/ void test_deque() { // TODO: Mark as TEST_CONSTEXPR_CXX26 once std::deque is constexpr + using Container = std::deque<std::deque<double>>; + Container c; + auto view = c | std::views::join; + Container::difference_type n = 0; + for (std::size_t i = 0; i < 10; ++i) { + n += i; + c.push_back(Container::value_type(i)); + } + assert(std::ranges::distance(view.begin(), view.end()) == n); +} + constexpr bool test() { { int a[] = {1, 2, 3}; @@ -197,7 +216,7 @@ constexpr bool test() { test_sized<contiguous_iterator<int*>, contiguous_iterator<int*>>(); { - using It = cpp20_input_iterator<int*>; // non-copyable, thus not a sentinel for itself + using It = cpp20_input_iterator<int*>; // non-copyable, thus not a sentinel for itself static_assert(!std::is_copy_constructible_v<It>); static_assert(!std::sentinel_for<It, It>); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&>); @@ -206,10 +225,10 @@ constexpr bool test() { static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&&, It&&>); } { - using It = cpp20_input_iterator<int*>; // non-copyable - using Sent = sentinel_wrapper<It>; // not a sized sentinel + using It = cpp20_input_iterator<int*>; // non-copyable + using Sent = sentinel_wrapper<It>; // not a sized sentinel static_assert(std::sentinel_for<Sent, It> && !std::sized_sentinel_for<Sent, It>); - int a[] = {1,2,3}; + int a[] = {1, 2, 3}; Sent last = Sent(It(a + 3)); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, Sent&>); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, Sent&&>); @@ -217,7 +236,7 @@ constexpr bool test() { assert(std::ranges::distance(It(a), Sent(It(a + 3))) == 3); } { - using It = cpp17_input_iterator<int*>; // not a sentinel for itself + using It = cpp17_input_iterator<int*>; // not a sentinel for itself static_assert(!std::sentinel_for<It, It>); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&>); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&&>); @@ -231,6 +250,26 @@ constexpr bool test() { static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int, int*>); static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int*, char*>); + { + using Container = std::vector<std::vector<int>>; + Container c; + auto view = c | std::views::join; + Container::difference_type n = 0; + for (std::size_t i = 0; i < 10; ++i) { + n += i; + c.push_back(Container::value_type(i)); + } + assert(std::ranges::distance(view.begin(), view.end()) == n); + } + { + using Container = std::array<std::array<char, 3>, 10>; + Container c; + auto view = c | std::views::join; + assert(std::ranges::distance(view.begin(), view.end()) == 30); + } + if (!TEST_IS_CONSTANT_EVALUATED) // TODO: Use TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED when std::deque is made constexpr + test_deque(); + return true; } diff --git a/libcxx/test/std/language.support/support.runtime/cstdalign.compile.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdalign.compile.pass.cpp index 69296df..d289ef6 100644 --- a/libcxx/test/std/language.support/support.runtime/cstdalign.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.runtime/cstdalign.compile.pass.cpp @@ -10,7 +10,7 @@ // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -// XFAIL: FROZEN-CXX03-HEADERS-FIXME +// UNSUPPORTED: c++03 #include <cstdalign> diff --git a/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp index 799a362..0184a38 100644 --- a/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp +++ b/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// // -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // <regex> // template <class BidirectionalIterator, class Allocator, class charT, class traits> diff --git a/libcxx/test/std/re/re.regex/re.regex.construct/bad_range.pass.cpp b/libcxx/test/std/re/re.regex/re.regex.construct/bad_range.pass.cpp index ecfdaee..cabd9eb 100644 --- a/libcxx/test/std/re/re.regex/re.regex.construct/bad_range.pass.cpp +++ b/libcxx/test/std/re/re.regex/re.regex.construct/bad_range.pass.cpp @@ -14,8 +14,6 @@ // template <class ST, class SA> // basic_regex(const basic_string<charT, ST, SA>& s); -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include <regex> #include <cassert> #include "test_macros.h" diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp index 5264e770..881a5d2 100644 --- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp @@ -226,7 +226,9 @@ constexpr bool test() { #ifdef _LIBCPP_VERSION // These types should be implicit-lifetime, but they are not guaranteed to be so. +# ifndef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR test_is_implicit_lifetime<std::pair<int, float>>(); +# endif test_is_implicit_lifetime<std::tuple<int, float>>(); #endif diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp index b7cc123..f7390ef 100644 --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp @@ -58,15 +58,18 @@ void test() { { { std::unique_ptr<WithCookie[]> ptr(new WithCookie[5]); + assert(&ptr[1] == ptr.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(ptr[6], "unique_ptr<T[]>::operator[](index): index out of range"); } { std::unique_ptr<WithCookie[]> ptr = std::make_unique<WithCookie[]>(5); + assert(&ptr[1] == ptr.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(ptr[6], "unique_ptr<T[]>::operator[](index): index out of range"); } #if TEST_STD_VER >= 20 { std::unique_ptr<WithCookie[]> ptr = std::make_unique_for_overwrite<WithCookie[]>(5); + assert(&ptr[1] == ptr.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(ptr[6] = WithCookie(), "unique_ptr<T[]>::operator[](index): index out of range"); } #endif @@ -82,11 +85,13 @@ void test() { { { std::unique_ptr<NoCookie[]> ptr = std::make_unique<NoCookie[]>(5); + assert(&ptr[1] == ptr.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(ptr[6], "unique_ptr<T[]>::operator[](index): index out of range"); } # if TEST_STD_VER >= 20 { std::unique_ptr<NoCookie[]> ptr = std::make_unique_for_overwrite<NoCookie[]>(5); + assert(&ptr[1] == ptr.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(ptr[6] = NoCookie(), "unique_ptr<T[]>::operator[](index): index out of range"); } # endif @@ -101,6 +106,7 @@ void test() { { std::unique_ptr<T[]> ptr = std::make_unique<T[]>(5); std::unique_ptr<T[]> other(std::move(ptr)); + assert(&other[1] == other.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(other[6], "unique_ptr<T[]>::operator[](index): index out of range"); } @@ -109,6 +115,7 @@ void test() { std::unique_ptr<T[]> ptr = std::make_unique<T[]>(5); std::unique_ptr<T[]> other; other = std::move(ptr); + assert(&other[1] == other.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(other[6], "unique_ptr<T[]>::operator[](index): index out of range"); } @@ -116,6 +123,7 @@ void test() { { std::unique_ptr<T[]> ptr = std::make_unique<T[]>(5); std::unique_ptr<T[], MyDeleter> other(std::move(ptr)); + assert(&other[1] == other.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(other[6], "unique_ptr<T[]>::operator[](index): index out of range"); } @@ -124,6 +132,7 @@ void test() { std::unique_ptr<T[]> ptr = std::make_unique<T[]>(5); std::unique_ptr<T[], MyDeleter> other; other = std::move(ptr); + assert(&other[1] == other.get() + 1); // ensure no assertion TEST_LIBCPP_ASSERT_FAILURE(other[6], "unique_ptr<T[]>::operator[](index): index out of range"); } }); @@ -144,6 +153,34 @@ struct WithCookie { char padding[Size]; }; +template <std::size_t Size> +struct alignas(128) OveralignedNoCookie { + char padding[Size]; +}; + +template <std::size_t Size> +struct alignas(128) OveralignedWithCookie { + OveralignedWithCookie() = default; + OveralignedWithCookie(OveralignedWithCookie const&) {} + OveralignedWithCookie& operator=(OveralignedWithCookie const&) { return *this; } + ~OveralignedWithCookie() {} + char padding[Size]; +}; + +// These types have a different ABI alignment (alignof) and preferred alignment (__alignof) on some platforms. +// Make sure things work with these types because array cookies can be sensitive to preferred alignment on some +// platforms. +struct WithCookiePreferredAlignment { + WithCookiePreferredAlignment() = default; + WithCookiePreferredAlignment(WithCookiePreferredAlignment const&) {} + WithCookiePreferredAlignment& operator=(WithCookiePreferredAlignment const&) { return *this; } + ~WithCookiePreferredAlignment() {} + long double data; +}; +struct NoCookiePreferredAlignment { + long double data; +}; + int main(int, char**) { test<WithCookie<1>, NoCookie<1>>(); test<WithCookie<2>, NoCookie<2>>(); @@ -153,7 +190,18 @@ int main(int, char**) { test<WithCookie<16>, NoCookie<16>>(); test<WithCookie<32>, NoCookie<32>>(); test<WithCookie<256>, NoCookie<256>>(); + + test<OveralignedWithCookie<1>, OveralignedNoCookie<1>>(); + test<OveralignedWithCookie<2>, OveralignedNoCookie<2>>(); + test<OveralignedWithCookie<3>, OveralignedNoCookie<3>>(); + test<OveralignedWithCookie<4>, OveralignedNoCookie<4>>(); + test<OveralignedWithCookie<8>, OveralignedNoCookie<8>>(); + test<OveralignedWithCookie<16>, OveralignedNoCookie<16>>(); + test<OveralignedWithCookie<32>, OveralignedNoCookie<32>>(); + test<OveralignedWithCookie<256>, OveralignedNoCookie<256>>(); + test<std::string, int>(); + test<WithCookiePreferredAlignment, NoCookiePreferredAlignment>(); return 0; } |