From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 61EC83858C98; Fri, 19 Jan 2024 19:13:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61EC83858C98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1705691612; bh=RxwIwKA0MInrqKip/y8/lgdwYdy8sEJ763T0xgjmiRE=; h=From:To:Subject:Date:From; b=FvSAZe+tAnRi6e7+V08Fz/+8j9QwDPp/ATGhQaQWU4FFjpUQaYpY8BARp9GMJxoMo d6CuReaMD5RxzzUSijFKp3xH1jXUnlxnHH44UapNvuntd8G82cFgZRUXaJHQDs1TU9 L4CgyQBHuCfXWQ79LFib2oXYKapclZddeNkoywlk= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-8292] libstdc++: Fix P2255R2 dangling checks for std::tuple in C++17 [PR108822] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: f1e5bf0d83ee4da81b6317c6d7f1278fe7eaa5a0 X-Git-Newrev: 502a3c03e40e8920afb734c077b045f6c5efd087 Message-Id: <20240119191332.61EC83858C98@sourceware.org> Date: Fri, 19 Jan 2024 19:13:32 +0000 (GMT) List-Id: https://gcc.gnu.org/g:502a3c03e40e8920afb734c077b045f6c5efd087 commit r14-8292-g502a3c03e40e8920afb734c077b045f6c5efd087 Author: Jonathan Wakely 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. Diff: --- libstdc++-v3/include/std/tuple | 2 +- .../testsuite/20_util/tuple/dangling_ref.cc | 156 ++++++++++++++------- 2 files changed, 110 insertions(+), 48 deletions(-) diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 7a045b3e6a1..be92f1eb973 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -1299,7 +1299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Error if construction from U... would create a dangling ref. # if __cpp_fold_expressions # define __glibcxx_dangling_refs(U) \ - (__reference_constructs_from_temporary(_Elements, U) && ...) + (__reference_constructs_from_temporary(_Elements, U) || ...) # else # define __glibcxx_dangling_refs(U) \ __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \ diff --git a/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc b/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc index 74fdc242349..b2dcf359438 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/dangling_ref.cc @@ -7,6 +7,7 @@ #if __cplusplus >= 202002L // For C++20 and later, constructors are constrained to disallow dangling. +static_assert(!std::is_constructible_v, long>); static_assert(!std::is_constructible_v, long, int>); static_assert(!std::is_constructible_v, int, long>); static_assert(!std::is_constructible_v, @@ -30,76 +31,137 @@ static_assert(!std::is_constructible_v, void test_ary_ctors() { - std::tuple t1(1L, 2); - // { dg-error "here" "" { target { c++17_down && hosted } } 33 } - // { dg-error "use of deleted function" "" { target c++20 } 33 } + std::tuple t1(1L); + // { dg-error "here" "" { target { c++17_down && hosted } } 34 } + // { dg-error "use of deleted function" "" { target c++20 } 34 } - std::tuple t2(1, 2L); - // { dg-error "here" "" { target { c++17_down && hosted } } 37 } - // { dg-error "use of deleted function" "" { target c++20 } 37 } + std::tuple t2(1L, 2); + // { dg-error "here" "" { target { c++17_down && hosted } } 38 } + // { dg-error "use of deleted function" "" { target c++20 } 38 } - std::tuple t3(1L, 2L); - // { dg-error "here" "" { target { c++17_down && hosted } } 41 } - // { dg-error "use of deleted function" "" { target c++20 } 41 } + std::tuple t3(1, 2L); + // { dg-error "here" "" { target { c++17_down && hosted } } 42 } + // { dg-error "use of deleted function" "" { target c++20 } 42 } - std::tuple t4(std::pair{}); - // { dg-error "here" "" { target { c++17_down && hosted } } 45 } - // { dg-error "use of deleted function" "" { target c++20 } 45 } + std::tuple t4(1L, 2L); + // { dg-error "here" "" { target { c++17_down && hosted } } 46 } + // { dg-error "use of deleted function" "" { target c++20 } 46 } - std::pair p; - std::tuple t5(p); + std::tuple t5(std::pair{}); // { dg-error "here" "" { target { c++17_down && hosted } } 50 } // { dg-error "use of deleted function" "" { target c++20 } 50 } + + std::pair p; + std::tuple t6(p); + // { dg-error "here" "" { target { c++17_down && hosted } } 55 } + // { dg-error "use of deleted function" "" { target c++20 } 55 } + + std::tuple t7(1L, 2, 3); + // { dg-error "here" "" { target { c++17_down && hosted } } 59 } + // { dg-error "use of deleted function" "" { target c++20 } 59 } } void test_converting_ctors() { - std::tuple t0; + std::tuple t10; + + std::tuple t11(t10); + // { dg-error "here" "" { target { c++17_down && hosted } } 69 } + // { dg-error "use of deleted function" "" { target c++20 } 69 } + + std::tuple t12(std::move(t10)); + // { dg-error "here" "" { target { c++17_down && hosted } } 73 } + // { dg-error "use of deleted function" "" { target c++20 } 73 } - std::tuple t1(t0); - // { dg-error "here" "" { target { c++17_down && hosted } } 60 } - // { dg-error "use of deleted function" "" { target c++20 } 60 } + std::tuple t20; - std::tuple t2(t0); - // { dg-error "here" "" { target { c++17_down && hosted } } 64 } - // { dg-error "use of deleted function" "" { target c++20 } 64 } + std::tuple t21(t20); + // { dg-error "here" "" { target { c++17_down && hosted } } 79 } + // { dg-error "use of deleted function" "" { target c++20 } 79 } - std::tuple t3(t0); - // { dg-error "here" "" { target { c++17_down && hosted } } 68 } - // { dg-error "use of deleted function" "" { target c++20 } 68 } + std::tuple t22(t20); + // { dg-error "here" "" { target { c++17_down && hosted } } 83 } + // { dg-error "use of deleted function" "" { target c++20 } 83 } - std::tuple t4(std::move(t0)); - // { dg-error "here" "" { target { c++17_down && hosted } } 72 } - // { dg-error "use of deleted function" "" { target c++20 } 72 } + std::tuple t23(t20); + // { dg-error "here" "" { target { c++17_down && hosted } } 87 } + // { dg-error "use of deleted function" "" { target c++20 } 87 } - std::tuple t5(std::move(t0)); - // { dg-error "here" "" { target { c++17_down && hosted } } 76 } - // { dg-error "use of deleted function" "" { target c++20 } 76 } + std::tuple t24(std::move(t20)); + // { dg-error "here" "" { target { c++17_down && hosted } } 91 } + // { dg-error "use of deleted function" "" { target c++20 } 91 } - std::tuple t6(std::move(t0)); - // { dg-error "here" "" { target { c++17_down && hosted } } 80 } - // { dg-error "use of deleted function" "" { target c++20 } 80 } + std::tuple t25(std::move(t20)); + // { dg-error "here" "" { target { c++17_down && hosted } } 95 } + // { dg-error "use of deleted function" "" { target c++20 } 95 } + + std::tuple t26(std::move(t20)); + // { dg-error "here" "" { target { c++17_down && hosted } } 99 } + // { dg-error "use of deleted function" "" { target c++20 } 99 } std::pair p0; - std::tuple t7(p0); - // { dg-error "here" "" { target { c++17_down && hosted } } 85 } - // { dg-error "use of deleted function" "" { target c++20 } 85 } + std::tuple t27(p0); + // { dg-error "here" "" { target { c++17_down && hosted } } 104 } + // { dg-error "use of deleted function" "" { target c++20 } 104 } - std::tuple t8(p0); - // { dg-error "here" "" { target { c++17_down && hosted } } 89 } - // { dg-error "use of deleted function" "" { target c++20 } 89 } + std::tuple t28(p0); + // { dg-error "here" "" { target { c++17_down && hosted } } 108 } + // { dg-error "use of deleted function" "" { target c++20 } 108 } - std::tuple t9(std::move(p0)); - // { dg-error "here" "" { target { c++17_down && hosted } } 93 } - // { dg-error "use of deleted function" "" { target c++20 } 93 } + std::tuple t29(std::move(p0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 112 } + // { dg-error "use of deleted function" "" { target c++20 } 112 } - std::tuple t10(std::move(p0)); - // { dg-error "here" "" { target { c++17_down && hosted } } 97 } - // { dg-error "use of deleted function" "" { target c++20 } 97 } + std::tuple t210(std::move(p0)); + // { dg-error "here" "" { target { c++17_down && hosted } } 116 } + // { dg-error "use of deleted function" "" { target c++20 } 116 } } -// TODO: test allocator-extended ctors -// TODO: test 1-tuple or 3-tuple, not just 2-tuple +#include + +void +test_allocator_extended_ctors() +{ + std::allocator a; + + std::tuple t1(std::allocator_arg, a, 1L); + // { dg-error "here" "" { target { c++17_down && hosted } } 128 } + // { dg-error "use of deleted function" "" { target c++20 } 128 } + + std::tuple t2(std::allocator_arg, a, 1L, 2); + // { dg-error "here" "" { target { c++17_down && hosted } } 132 } + // { dg-error "use of deleted function" "" { target c++20 } 132 } + + std::tuple tl; + + std::tuple t3(std::allocator_arg, a, tl); + // { dg-error "here" "" { target { c++17_down && hosted } } 138 } + // { dg-error "use of deleted function" "" { target c++20 } 138 } + + std::tuple t4(std::allocator_arg, a, std::move(tl)); + // { dg-error "here" "" { target { c++17_down && hosted } } 142 } + // { dg-error "use of deleted function" "" { target c++20 } 142 } + + std::tuple tll; + + std::tuple t5(std::allocator_arg, a, tll); + // { dg-error "here" "" { target { c++17_down && hosted } } 148 } + // { dg-error "use of deleted function" "" { target c++20 } 148 } + + std::tuple t6(std::allocator_arg, a, std::move(tll)); + // { dg-error "here" "" { target { c++17_down && hosted } } 152 } + // { dg-error "use of deleted function" "" { target c++20 } 152 } + + std::pair pll; + + std::tuple t7(std::allocator_arg, a, pll); + // { dg-error "here" "" { target { c++17_down && hosted } } 158 } + // { dg-error "use of deleted function" "" { target c++20 } 158 } + + std::tuple t8(std::allocator_arg, a, std::move(pll)); + // { dg-error "here" "" { target { c++17_down && hosted } } 162 } + // { dg-error "use of deleted function" "" { target c++20 } 162 } +} // { dg-error "static assert.* dangling reference" "" { target { c++17_down && hosted } } 0 }