]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Implement P2255R2 dangling checks for std::pair
authorJonathan Wakely <jwakely@redhat.com>
Wed, 8 Feb 2023 12:58:45 +0000 (12:58 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 16 Feb 2023 14:38:38 +0000 (14:38 +0000)
commit916ce577ad109be69a3100fc79b3933d741eb990
tree76e1fc2fd9e4f6372c08cc4f34a020ae20253e09
parent866555b170016c49beb869a78cbecdeb07c63135
libstdc++: Implement P2255R2 dangling checks for std::pair

This uses the new __reference_constructs_from_temporary built-in to
identify when a std::pair constructor will bind a reference to a
temporary that goes out of scope at the end of the constructor.  For
example, std::pair<const long&, int> p(1, 2); will call the pair<const
long&, int>::pair(U1&&, U2&&) constructor with U1=int and U2=int. In the
constructor body a temporary long will be created and the p.first member
will bind to that temporary. When the constructor returns, the reference
is immediately dangling. P2255 requires the constructor to be deleted to
prevent this bug.

Although P2255 was approved for C++23, it fixes a longstanding LWG issue
in older standards, and it turns silent runtime undefined behaviour into
a compilation error. Because of that, the dangling checks are applied
all the way back to C++98.  However, if these changes cause too much
code to be rejected (e.g. in cases where the dangling reference is never
used after the constructor returns) then we can consider removing them
for C++20 and older standards.

The affected constructors are deleted for C++20 and later, when concepts
are available to simplify the constructor constraints. For C++17 and
earlier the overload sets are complicated and awkward to maintain, so
the dangling checks are done in static assertions in the constructor
bodies, instead of being SFINAE-friendly constraints. The pre-C++17
assertions are only enabled for Debug Mode, to avoid introducing a
breaking change in Stage 4. We should consider enabling them by default
in Stage 1 for GCC 14.

libstdc++-v3/ChangeLog:

* include/bits/stl_pair.h (pair) [C++20]: Add non-dangling
constraints to constructors and add deleted overloads for the
dangling cases, as per P2255R2.
(pair) [!C++20 && _GLIBCXX_DEBUG]: Add static assertions to
make dangling cases ill-formed.
* testsuite/20_util/pair/dangling_ref.cc: New test.
libstdc++-v3/include/bits/stl_pair.h
libstdc++-v3/testsuite/20_util/pair/dangling_ref.cc [new file with mode: 0644]