// { dg-options "-lstdc++exp" } // { dg-do run { target c++23 } } // { dg-require-cpp-feature-test __cpp_lib_stacktrace } #include #include "testsuite_allocator.h" static_assert( std::is_nothrow_default_constructible_v ); static_assert( std::is_copy_constructible_v ); static_assert( std::is_nothrow_move_constructible_v ); static_assert( std::is_copy_assignable_v ); static_assert( std::is_nothrow_move_assignable_v ); static_assert( std::is_nothrow_swappable_v ); void test_cons() { { using Stacktrace = std::stacktrace; using Alloc = Stacktrace::allocator_type; Stacktrace s0; VERIFY( s0.empty() ); VERIFY( s0.size() == 0 ); VERIFY( s0.begin() == s0.end() ); Stacktrace s1(Alloc{}); VERIFY( s1.empty() ); VERIFY( s1.size() == 0 ); VERIFY( s1.begin() == s1.end() ); VERIFY( s0 == s1 ); Stacktrace s2(s0); VERIFY( s2 == s0 ); const Stacktrace curr = Stacktrace::current(); Stacktrace s3(curr); VERIFY( ! s3.empty() ); VERIFY( s3.size() != 0 ); VERIFY( s3.begin() != s3.end() ); VERIFY( s3 != s0 ); Stacktrace s4(s3); VERIFY( ! s4.empty() ); VERIFY( s4.size() != 0 ); VERIFY( s4.begin() != s4.end() ); VERIFY( s4 == s3 ); VERIFY( s4 != s0 ); Stacktrace s5(std::move(s3)); VERIFY( ! s5.empty() ); VERIFY( s5.size() != 0 ); VERIFY( s5.begin() != s5.end() ); VERIFY( s5 == s4 ); VERIFY( s5 != s0 ); VERIFY( s3 == s0 ); Stacktrace s6(s4, Alloc{}); VERIFY( s6 == s4 ); Stacktrace s7(std::move(s6), Alloc{}); VERIFY( s7 == s4 ); } { using Alloc = __gnu_test::uneq_allocator; using Stacktrace = std::basic_stacktrace; Stacktrace s0; VERIFY( s0.empty() ); VERIFY( s0.size() == 0 ); VERIFY( s0.begin() == s0.end() ); Stacktrace s1(Alloc{}); VERIFY( s1.empty() ); VERIFY( s1.size() == 0 ); VERIFY( s1.begin() == s1.end() ); VERIFY( s0 == s1 ); Stacktrace s2(s0); VERIFY( s2 == s0 ); const Stacktrace curr = Stacktrace::current(); Stacktrace s3(curr); VERIFY( ! s3.empty() ); VERIFY( s3.size() != 0 ); VERIFY( s3.begin() != s3.end() ); VERIFY( s3 != s0 ); Stacktrace s4(s3); VERIFY( ! s4.empty() ); VERIFY( s4.size() != 0 ); VERIFY( s4.begin() != s4.end() ); VERIFY( s4 == s3 ); VERIFY( s4 != s0 ); Stacktrace s5(std::move(s3)); VERIFY( ! s5.empty() ); VERIFY( s5.size() != 0 ); VERIFY( s5.begin() != s5.end() ); VERIFY( s5 == s4 ); VERIFY( s5 != s0 ); VERIFY( s3 == s0 ); // TODO test allocator-extended copy/move // TODO test allocator propagation } } void test_assign() { { using Stacktrace = std::stacktrace; Stacktrace s0; s0 = s0; VERIFY( s0.empty() ); s0 = std::move(s0); VERIFY( s0.empty() ); Stacktrace s1 = Stacktrace::current(); VERIFY( s1 != s0 ); s0 = s1; VERIFY( s0 == s1 ); VERIFY( s0.at(0).source_line() == (__LINE__ - 4) ); s1 = Stacktrace::current(); VERIFY( s1 != s0 ); Stacktrace s2 = s0; Stacktrace s3 = s1; s0 = std::move(s1); VERIFY( s0 == s3 ); VERIFY( s1 == s2 ); // ISO C++: valid but unspecified; GCC: swapped. } { using Alloc = __gnu_test::uneq_allocator; using Stacktrace = std::basic_stacktrace; Stacktrace s0; s0 = s0; VERIFY( s0.empty() ); s0 = std::move(s0); VERIFY( s0.empty() ); Stacktrace s1 = Stacktrace::current(); VERIFY( s1 != s0 ); s0 = s1; VERIFY( s0 == s1 ); s1 = Stacktrace::current(Alloc(__LINE__)); VERIFY( s1 != s0 ); s0 = std::move(s1); VERIFY( s0.at(0).source_line() == s0.get_allocator().get_personality() ); VERIFY( s1.empty() ); // ISO C++: valid but unspecified; GCC: empty. Stacktrace s2 = Stacktrace::current(s0.get_allocator()); Stacktrace s3 = s2; s2 = std::move(s0); VERIFY( s2.at(0).source_line() == s2.get_allocator().get_personality() ); VERIFY( s0 == s3 ); // ISO C++: valid but unspecified, GCC: swapped. } } void test_swap() { { using Stacktrace = std::stacktrace; Stacktrace s0; Stacktrace s1 = Stacktrace::current(); swap(s0, s1); VERIFY( s1.empty() ); VERIFY( ! s0.empty() ); } { using Alloc = __gnu_test::uneq_allocator; using Stacktrace = std::basic_stacktrace; Stacktrace s0; Stacktrace s1 = Stacktrace::current(); swap(s0, s1); VERIFY( s1.empty() ); VERIFY( ! s0.empty() ); // TODO test allocator propagation } } void test_pr105031() { // PR libstdc++/105031 // wrong constexpr if statement in operator=(basic_stacktrace&&) using Alloc = __gnu_test::uneq_allocator; std::basic_stacktrace s; s = auto(s); } int main() { test_cons(); test_assign(); test_swap(); test_pr105031(); }