Bug 108822 - [C++23] Implement P2255R2, type trait to detect reference binding to temporary
Summary: [C++23] Implement P2255R2, type trait to detect reference binding to temporary
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: 14.0
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on: 104477
Blocks: c++23-lib
  Show dependency treegraph
 
Reported: 2023-02-16 15:36 UTC by Jonathan Wakely
Modified: 2024-01-19 19:13 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-02-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2023-02-16 15:36:55 UTC
Tracker bug for the library side of https://wg21.link/p2255r2
Comment 1 Jonathan Wakely 2023-02-16 15:39:39 UTC
The new type traits were added in r13-1714-g9a15d3beace26d

The std::invoke changes were added in r13-2922-gfa9bda3ea4315a

The std::pair changes were added in r13-6084-g916ce577ad109b

The std::tuple changes are not done yet (I have a partial patch).
Comment 2 Richard Biener 2023-04-26 06:57:51 UTC
GCC 13.1 is being released, retargeting bugs to GCC 13.2.
Comment 3 Richard Biener 2023-07-27 09:25:24 UTC
GCC 13.2 is being released, retargeting bugs to GCC 13.3.
Comment 4 GCC Commits 2024-01-13 11:16:01 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

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

commit r14-7225-gf8a5298c97c460d45e888b123fe1bbcdb49b8ad4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jan 10 17:29:22 2024 +0000

    libstdc++: Implement P2255R2 dangling checks for std::tuple [PR108822]
    
    This is the last part of PR libstdc++/108822 implementing P2255R2, which
    makes it ill-formed to create a std::tuple that would bind a reference
    to a temporary.
    
    The dangling checks are implemented as deleted constructors for C++20
    and higher, and as Debug Mode static assertions in the constructor body
    for older standards. This is similar to the r13-6084-g916ce577ad109b
    changes for std::pair.
    
    As part of this change, I've reimplemented most of std::tuple for C++20,
    making use of concepts to replace the enable_if constraints, and using
    conditional explicit to avoid duplicating most constructors. We could
    use conditional explicit for the C++11 implementation too (with pragmas
    to disables the -Wc++17-extensions warnings), but that should be done as
    a stage 1 change for GCC 15 rather than now.
    
    The partial specialization for std::tuple<T1, T2> is no longer used for
    C++20 (or more precisely, for a C++20 compiler that supports concepts
    and conditional explicit). The additional constructors and assignment
    operators that take std::pair arguments have been added to the C++20
    implementation of the primary template, with sizeof...(_Elements)==2
    constraints. This avoids reimplementing all the other constructors in
    the std::tuple<T1, T2> partial specialization to use concepts. This way
    we avoid four implementations of every constructor and only have three!
    (The primary template has an implementation of each constructor for
    C++11 and another for C++20, and the tuple<T1,T2> specialization has an
    implementation of each for C++11, so that's three for each constructor.)
    
    In order to make the constraints more efficient on the C++20 version of
    the default constructor I've also added a variable template for the
    __is_implicitly_default_constructible trait, implemented using concepts.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/108822
            * include/std/tuple (tuple): Add checks for dangling references.
            Reimplement constraints and constant expressions using C++20
            features.
            * include/std/type_traits [C++20]
            (__is_implicitly_default_constructible_v): Define.
            (__is_implicitly_default_constructible): Use variable template.
            * testsuite/20_util/tuple/dangling_ref.cc: New test.
    
    Reviewed-by: Patrick Palka <ppalka@redhat.com>
Comment 5 Jonathan Wakely 2024-01-13 11:22:30 UTC
Done for GCC 14
Comment 6 GCC Commits 2024-01-15 19:02:20 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

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

commit r14-7256-g1e88a151f878e0a139bf55eb0cee2506fb903274
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jan 15 16:51:39 2024 +0000

    libstdc++: Fix redefinition error in std::tuple [PR108822]
    
    When using a compiler that doesn't define __cpp_conditional_explicit
    there's a redefinition error for tuple::__nothrow_assignable. This is
    because it's defined in different places for the pre-C++20 and C++20
    implementations, which are controled by different preprocessor
    conditions. For certain combinations of C++20 feature test macros it's
    possible for both __nothrow_assignable definitions to be in scope.
    
    Move the pre-C++20 __assignable and __nothrow_assignable definitions adjacent to
    their use, so that only one set of definitions is visible for any given
    set of feature test macros.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/108822
            * include/std/tuple (__assignable, __is_nothrow_assignable):
            Move pre-C++20 definitions adjacent to their use.
Comment 7 GCC Commits 2024-01-19 19:13:33 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:502a3c03e40e8920afb734c077b045f6c5efd087

commit r14-8292-g502a3c03e40e8920afb734c077b045f6c5efd087
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jan 19 12:28:30 2024 +0000

    libstdc++: Fix P2255R2 dangling checks for std::tuple in C++17 [PR108822]
    
    I accidentally used && in a fold-expression instead of || which meant
    that in C++17 the tuple(UElements&&...) constructor only failed its
    debug assertion if all tuple elements were dangling references. Some
    missing tests (noted as "TODO") meant this wasn't tested.
    
    This fixes the fold expression and adds the missing tests.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/108822
            * include/std/tuple (__glibcxx_no_dangling_refs) [C++17]: Fix
            wrong fold-operator.
            * testsuite/20_util/tuple/dangling_ref.cc: Check tuples with one
            element and three elements. Check allocator-extended
            constructors.