blob: 8dfdf4739bee6abe28142f65b29cffa6bc34ae6a [file] [log] [blame]
// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
// { dg-do run { target c++23 } }
// { dg-require-effective-target stacktrace }
#include <stacktrace>
#include "testsuite_allocator.h"
static_assert( std::is_nothrow_default_constructible_v<std::stacktrace> );
static_assert( std::is_copy_constructible_v<std::stacktrace> );
static_assert( std::is_nothrow_move_constructible_v<std::stacktrace> );
static_assert( std::is_copy_assignable_v<std::stacktrace> );
static_assert( std::is_nothrow_move_assignable_v<std::stacktrace> );
static_assert( std::is_nothrow_swappable_v<std::stacktrace> );
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<std::stacktrace_entry>;
using Stacktrace = std::basic_stacktrace<Alloc>;
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<std::stacktrace_entry>;
using Stacktrace = std::basic_stacktrace<Alloc>;
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<std::stacktrace_entry>;
using Stacktrace = std::basic_stacktrace<Alloc>;
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::stacktrace_entry>;
std::basic_stacktrace<Alloc> s;
s = auto(s);
}
int main()
{
test_cons();
test_assign();
test_swap();
test_pr105031();
}