https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108619

--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-14 branch has been updated by Jonathan Wakely
<r...@gcc.gnu.org>:

https://gcc.gnu.org/g:1be3e4e43839d313364ffa99012ada41b4fae8da

commit r14-10705-g1be3e4e43839d313364ffa99012ada41b4fae8da
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Jul 10 23:14:19 2024 +0100

    libstdc++: Fix std::allocator_traits::construct constraints [PR108619]

    Using std::is_constructible in the constraints introduces a spurious
    dependency on the type being destructible, which should not be required
    for constructing with an allocator. The test case shows a case where the
    type has a private destructor, which can be destroyed by the allocator,
    but std::is_destructible and std::is_constructible are false.

    Similarly, using is_nothrow_constructible in the noexcept-specifiers
    for the construct members of allocator_traits and std::allocator,
    __gnu_cxx::__new_allocator, and __gnu_cxx::__malloc_allocator gives the
    wrong answer if the type isn't destructible.
    We need a new type trait to define those correctly, so that we only
    check if the placement new-expression is nothrow after using
    is_constructible to check that it would be well-formed.

    On trunk all members of std::allocator_traits were rewritten in terms of
    'if constexpr' using variable templates and the detection idiom. For the
    release branch this backport only changes the 'construct' member.

    Although we can use 'if constexpr' and variable templates in C++11 with
    appropriate uses of diagnostic pragmas, we can't have constexpr
    functions with multiple return statements. This means that in C++11 mode
    the _S_nothrow_construct helper used for noexcept-specifiers still needs
    to be a pair of overloads using enable_if.

    libstdc++-v3/ChangeLog:

            PR libstdc++/108619
            * include/bits/alloc_traits.h (__allocator_traits_base): Add
            variable templates for detecting whether the allocator has a
            construct member, or if placement new can be used instead.
            (allocator_traits::__construct_helper): Remove.
            (allocator_traits::__has_construct): Remove.
            (allocator_traits::construct): Use 'if constexpr' instead of
            dispatching to overloads constrained with enable_if.
            (allocator_traits<allocator<T>>::construct): Use _Construct if
            construct_at is not supported. Use
            __is_nothrow_new_constructible for noexcept-specifier.
            (allocator_traits<allocator<void>>::construct): Use
            __is_nothrow_new_constructible for noexcept-specifier.
            * include/bits/new_allocator.h (construct): Likewise.
            * include/ext/malloc_allocator.h (construct): Likewise.
            * include/std/type_traits (__is_nothrow_new_constructible): New
            variable template.
            * testsuite/20_util/allocator/89510.cc: Adjust expected results.
            * testsuite/ext/malloc_allocator/89510.cc: Likewise.
            * testsuite/ext/new_allocator/89510.cc: Likewise.
            * testsuite/20_util/allocator_traits/members/108619.cc: New test.

    (cherry picked from commit 8cf51d7516b92b352c358c14ab4e456ae53c3371)

Reply via email to