public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Tamar Christina <tnfchris@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] libstdc++: Replace deduced return type in ranges::iter_move (PR 92894) Date: Fri, 17 Jul 2020 14:58:53 +0000 (GMT) [thread overview] Message-ID: <20200717145853.C6153394D8AB@sourceware.org> (raw) https://gcc.gnu.org/g:6fedf28c7921f125be75a9f688a7b845a1b5663b commit 6fedf28c7921f125be75a9f688a7b845a1b5663b Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu May 7 17:39:56 2020 +0100 libstdc++: Replace deduced return type in ranges::iter_move (PR 92894) The deduced return type causes the instantiation of the function body, which can then require the instantiation of std::projected::operator* which is intentionally not defined. This patch uses a helper trait to define the return type, so that the function body doesn't need to be instantiated. Unlike on the master branch, this backport to gcc-10 does not change the iter_rvalue_reference_t alias template and __indirectly_readable_impl concept to use the new trait. Backport from mainline 2020-05-01 Jonathan Wakely <jwakely@redhat.com> Patrick Palka <ppalka@redhat.com> PR libstdc++/92894 * include/bits/iterator_concepts.h (ranges::__cust_imove::_IMove): Add trait to determine return type and an alias for it. (ranges::__cust_imove::_IMove::operator()): Use __result instead of deduced return type. * testsuite/24_iterators/customization_points/92894.cc: New test. * testsuite/24_iterators/indirect_callable/92894.cc: New test. Co-authored-by: Patrick Palka <ppalka@redhat.com> Diff: --- libstdc++-v3/ChangeLog | 14 ++++++ libstdc++-v3/include/bits/iterator_concepts.h | 28 +++++++++-- .../24_iterators/customization_points/92894.cc | 52 ++++++++++++++++++++ .../24_iterators/indirect_callable/92894.cc | 55 ++++++++++++++++++++++ 4 files changed, 144 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 70e296622e7..55d975b84fc 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2020-05-07 Jonathan Wakely <jwakely@redhat.com> + + Backport from mainline + 2020-05-01 Jonathan Wakely <jwakely@redhat.com> + Patrick Palka <ppalka@redhat.com> + + PR libstdc++/92894 + * include/bits/iterator_concepts.h (ranges::__cust_imove::_IMove): + Add trait to determine return type and an alias for it. + (ranges::__cust_imove::_IMove::operator()): Use __result instead of + deduced return type. + * testsuite/24_iterators/customization_points/92894.cc: New test. + * testsuite/24_iterators/indirect_callable/92894.cc: New test. + 2020-05-07 Release Manager * GCC 10.1.0 released. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index b598532089e..c5b6247cde7 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -89,6 +89,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _IMove { private: + template<typename _Tp> + struct __result + { using type = iter_reference_t<_Tp>; }; + + template<typename _Tp> + requires __adl_imove<_Tp> + struct __result<_Tp> + { using type = decltype(iter_move(std::declval<_Tp>())); }; + + template<typename _Tp> + requires (!__adl_imove<_Tp>) + && is_lvalue_reference_v<iter_reference_t<_Tp>> + struct __result<_Tp> + { using type = remove_reference_t<iter_reference_t<_Tp>>&&; }; + template<typename _Tp> static constexpr bool _S_noexcept() @@ -100,16 +115,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } public: - template<typename _Tp> - requires __adl_imove<_Tp> || requires(_Tp& __e) { *__e; } - constexpr decltype(auto) + // The result type of iter_move(std::declval<_Tp>()) + template<std::__detail::__dereferenceable _Tp> + using __type = typename __result<_Tp>::type; + + template<std::__detail::__dereferenceable _Tp> + constexpr __type<_Tp> operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>()) { if constexpr (__adl_imove<_Tp>) return iter_move(static_cast<_Tp&&>(__e)); - else if constexpr (is_reference_v<iter_reference_t<_Tp>>) - return std::move(*__e); + else if constexpr (is_lvalue_reference_v<iter_reference_t<_Tp>>) + return static_cast<__type<_Tp>>(*__e); else return *__e; } diff --git a/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc b/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc new file mode 100644 index 00000000000..197268fe5e3 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <iterator> + +using namespace std; + +// Define our own of version of indirectly_readable_impl here, +// to check the use of iter_move even if the real concept in +// <bits/iterator_concepts.h> no longer uses iter_move. +template<class In> +concept indirectly_readable_impl + = requires(const In in) + { + typename iter_value_t<In>; + typename iter_reference_t<In>; + typename iter_rvalue_reference_t<In>; + { *in } -> same_as<iter_reference_t<In>>; + { ranges::iter_move(in) } -> same_as<iter_rvalue_reference_t<In>>; + }; + +template<class T> requires indirectly_readable_impl<projected<T*, identity>> + void algo(T) + { } + +void +test01() +{ + // PR libstdc++/92894 + // Verify that the use of range::iter_move above doesn't cause odr-use of + // projected<local-class-type, identity>::operator* (which is not defined). + struct X { }; + X a; + algo(a); +} diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc b/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc new file mode 100644 index 00000000000..3408c76bde1 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <iterator> + +using std::projected; +using std::identity; +using std::indirect_unary_predicate; + +template<typename T, + indirect_unary_predicate<projected<T*, identity>> Pred> + constexpr void + all_of(T*, Pred) + { } + +void +test01() +{ + // PR libstdc++/92894 + struct X { }; + X x; + all_of(&x, [](X&) { return false; }); +} + +template<class R, class Proj = identity, + indirect_unary_predicate<projected<R, Proj>> Pred> + constexpr void + find_if(R, Pred, Proj = {}) + { } + +void +test02() +{ + // PR 94241 + struct s { int m; }; + s r[] = { s{0}, s{1}, s{2}, s{3} }; + find_if(r, [](auto const) { return true; }); +}
reply other threads:[~2020-07-17 14:58 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200717145853.C6153394D8AB@sourceware.org \ --to=tnfchris@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).