https://gcc.gnu.org/g:fe04901737112abb6b1a71fe645f727384dc986a

commit r15-5761-gfe04901737112abb6b1a71fe645f727384dc986a
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Nov 28 10:24:00 2024 +0000

    libstdc++: Fix allocator-extended move ctor for std::basic_stacktrace 
[PR117822]
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/117822
            * include/std/stacktrace (stacktrace(stacktrace&&, const A&)):
            Fix typo in qualified-id for is_always_equal trait.
            * testsuite/19_diagnostics/stacktrace/stacktrace.cc: Test
            allocator-extended constructors and allocator propagation.

Diff:
---
 libstdc++-v3/include/std/stacktrace                |   2 +-
 .../19_diagnostics/stacktrace/stacktrace.cc        | 207 ++++++++++++++++++++-
 2 files changed, 204 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index 58d0c2a0fc22..2c0f6ba10a91 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -295,7 +295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                       const allocator_type& __alloc) noexcept
       : _M_alloc(__alloc)
       {
-       if constexpr (_Allocator::is_always_equal::value)
+       if constexpr (_AllocTraits::is_always_equal::value)
          _M_impl = std::__exchange(__other._M_impl, {});
        else if (_M_alloc == __other._M_alloc)
          _M_impl = std::__exchange(__other._M_impl, {});
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 6bb22eacd92c..ee1a6d221e3a 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -106,12 +106,164 @@ test_cons()
     VERIFY( s5 != s0 );
     VERIFY( s3 == s0 );
 
-    // TODO test allocator-extended copy/move
+    Stacktrace s6(s5, Alloc{6});
+    VERIFY( ! s6.empty() );
+    VERIFY( s6.size() != 0 );
+    VERIFY( s6.begin() != s6.end() );
+    VERIFY( s6 == s5 );
+    VERIFY( s5 != s0 );
+    VERIFY( s6.get_allocator().get_personality() == 6 );
 
-    // TODO test allocator propagation
+    Stacktrace s7(std::move(s6), Alloc{7});
+    VERIFY( ! s7.empty() );
+    VERIFY( s7.size() != 0 );
+    VERIFY( s7.begin() != s7.end() );
+    VERIFY( s7 == s5 );
+    VERIFY( s5 != s0 );
+    VERIFY( s7.get_allocator().get_personality() == 7 );
   }
-}
 
+  {
+    using Alloc = __gnu_test::SimpleAllocator<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 );
+
+    Stacktrace s6(s5, Alloc{});
+    VERIFY( ! s6.empty() );
+    VERIFY( s6.size() != 0 );
+    VERIFY( s6.begin() != s6.end() );
+    VERIFY( s6 == s5 );
+    VERIFY( s5 != s0 );
+
+    Stacktrace s7(std::move(s6), Alloc{});
+    VERIFY( ! s7.empty() );
+    VERIFY( s7.size() != 0 );
+    VERIFY( s7.begin() != s7.end() );
+    VERIFY( s7 == s5 );
+    VERIFY( s5 != s0 );
+  }
+
+{
+    using Stacktrace = std::pmr::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 );
+
+    __gnu_test::memory_resource mr;
+    Stacktrace s6(s5, &mr);
+    VERIFY( ! s6.empty() );
+    VERIFY( s6.size() != 0 );
+    VERIFY( s6.begin() != s6.end() );
+    VERIFY( s6 == s5 );
+    VERIFY( s5 != s0 );
+    VERIFY( s6.get_allocator() != s5.get_allocator() );
+
+    Stacktrace s7(std::move(s6), Alloc{});
+    VERIFY( ! s7.empty() );
+    VERIFY( s7.size() != 0 );
+    VERIFY( s7.begin() != s7.end() );
+    VERIFY( s7 == s5 );
+    VERIFY( s5 != s0 );
+    VERIFY( s7.get_allocator() != s6.get_allocator() );
+  }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, false>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
+
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(s1);
+    VERIFY( s2.get_allocator() != s1.get_allocator() );
+    Stacktrace s3(std::move(s1));
+    VERIFY( s3.get_allocator() == s1.get_allocator() );
+  }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, true>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
+
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(s1);
+    VERIFY( s2.get_allocator() == s1.get_allocator() );
+    Stacktrace s3(std::move(s1));
+    VERIFY( s3.get_allocator() == s1.get_allocator() );
+  }
+}
 
 void
 test_assign()
@@ -167,6 +319,32 @@ test_assign()
     VERIFY( s2.at(0).source_line() == s2.get_allocator().get_personality() );
     VERIFY( s0 == s3 ); // ISO C++: valid but unspecified, GCC: swapped.
   }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, false>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
+
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(Alloc{2});
+    s2 = s1;
+    VERIFY( s2.get_allocator() != s1.get_allocator() );
+    s1 = std::move(s2);
+    VERIFY( s1.get_allocator() != s2.get_allocator() );
+  }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, true>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
+
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(Alloc{2});
+    s2 = s1;
+    VERIFY( s2.get_allocator() == s1.get_allocator() );
+    s1 = Stacktrace::current(Alloc{3});
+    VERIFY( s1.get_allocator().get_personality() == 3 );
+  }
 }
 
 void
@@ -191,8 +369,29 @@ test_swap()
     swap(s0, s1);
     VERIFY( s1.empty() );
     VERIFY( ! s0.empty() );
+  }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, false>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
+
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(Alloc{1}); // Must use equal allocators when not propagating.
+    swap(s1, s2);
+    VERIFY( s1.get_allocator() == s2.get_allocator() );
+  }
+
+  {
+    using Alloc
+      = __gnu_test::propagating_allocator<std::stacktrace_entry, true>;
+    using Stacktrace = std::basic_stacktrace<Alloc>;
 
-    // TODO test allocator propagation
+    Stacktrace s1 = Stacktrace::current(Alloc{1});
+    Stacktrace s2(Alloc{2});
+    swap(s1, s2);
+    VERIFY( s1.get_allocator().get_personality() == 2 );
+    VERIFY( s2.get_allocator().get_personality() == 1 );
   }
 }

Reply via email to