summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc')
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc215
1 files changed, 215 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
new file mode 100644
index 00000000000..8dfdf4739be
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -0,0 +1,215 @@
+// { 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();
+}