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

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

https://gcc.gnu.org/g:8cf51d7516b92b352c358c14ab4e456ae53c3371

commit r15-3132-g8cf51d7516b92b352c358c14ab4e456ae53c3371
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.

    Instead of just fixing the overly restrictive constraint to check for
    placement new, rewrite allocator_traits in terms of 'if constexpr' using
    variable templates and the detection idiom.

    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 and _S_nothrow_destroy helpers used for
    noexcept-specifiers still need to be overlaods using enable_if. Nearly
    everything else can be simplified to reduce overload resolution and
    enable_if checks.

    libstdc++-v3/ChangeLog:

            PR libstdc++/108619
            * include/bits/alloc_traits.h (__allocator_traits_base): Add
            variable templates for detecting which allocator operations are
            supported.
            (allocator_traits): 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.

Reply via email to