gcc/libstdc++-v3/testsuite/20_util/pair/dangling_ref.cc

68 lines
2.7 KiB
C++
Raw Permalink Normal View History

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.
2023-02-08 12:58:45 +00:00
// { dg-do compile { target c++11 } }
// { dg-options "-Wno-unused-variable" }
// { dg-additional-options "-D_GLIBCXX_DEBUG" { target c++17_down } }
// { dg-skip-if "cannot mix with DEBUG" { *-*-* } { "-D_GLIBCXX_PARALLEL" } }
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.
2023-02-08 12:58:45 +00:00
#include <utility>
#if __cplusplus >= 202002L
// For C++20 and later, constructors are constrained to disallow dangling.
static_assert(!std::is_constructible_v<std::pair<const int&, int>, long, int>);
static_assert(!std::is_constructible_v<std::pair<int, const int&>, int, long>);
static_assert(!std::is_constructible_v<std::pair<const int&, int>,
std::pair<long, long>>);
static_assert(!std::is_constructible_v<std::pair<int, const int&>,
std::pair<long, long>>);
static_assert(!std::is_constructible_v<std::pair<const int&, int>,
const std::pair<long, long>&>);
static_assert(!std::is_constructible_v<std::pair<int, const int&>,
const std::pair<long, long>&>);
#endif
void
test_binary_ctors()
{
std::pair<const int&, int> p1(1L, 2);
// { dg-error "here" "" { target { c++17_down && hosted } } 24 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 24 }
std::pair<int, const int&> p2(1, 2L);
// { dg-error "here" "" { target { c++17_down && hosted } } 28 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 28 }
std::pair<const int&, const int&> p3(1L, 2L);
// { dg-error "here" "" { target { c++17_down && hosted } } 32 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 32 }
}
void
test_converting_ctors()
{
std::pair<long, long> p0;
std::pair<const int&, int> p1(p0);
// { dg-error "here" "" { target { c++17_down && hosted } } 42 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 42 }
std::pair<int, const int&> p2(p0);
// { dg-error "here" "" { target { c++17_down && hosted } } 46 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 46 }
std::pair<const int&, const int&> p3(p0);
// { dg-error "here" "" { target { c++17_down && hosted } } 50 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 50 }
std::pair<const int&, int> p4(std::move(p0));
// { dg-error "here" "" { target { c++17_down && hosted } } 54 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 54 }
std::pair<int, const int&> p5(std::move(p0));
// { dg-error "here" "" { target { c++17_down && hosted } } 58 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 58 }
std::pair<const int&, const int&> p6(std::move(p0));
// { dg-error "here" "" { target { c++17_down && hosted } } 62 }
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.
2023-02-08 12:58:45 +00:00
// { dg-error "use of deleted function" "" { target c++20 } 62 }
}
// { dg-error "static assert.* dangling reference" "" { target { c++17_down && hosted } } 0 }