From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2136) id 50874398E812; Wed, 17 Jun 2020 21:41:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 50874398E812 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1592430103; bh=hlx6/4JH5n0kne1a3wuT4oiVMu3hP3791gK+qiBox+8=; h=From:To:Subject:Date:From; b=EuFHyt/03jELqZr5jXfTtGgmF15rdCLLmmc3kYzXd45kPv2Om/AeuGgMYemYjv9aL 6RFaVu1lAxbWOu1qcEoGd3n9AfWAkHQnxEkbgt0/m4EbNAMPEkjNrYi5hhLOaCNsqN WhhVr55NhhLWWWUNrtcHlP5ehooEnH8J17bI+gWw= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Aldy Hernandez To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: Avoid constraint recursion with iterator_traits (PR 93983) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/devel/ranger X-Git-Oldrev: 48c28b17a9de54a402b92e0564f64afe4d3f83e5 X-Git-Newrev: f094665d465cdf8903797cc58bea13007e588616 Message-Id: <20200617214143.50874398E812@sourceware.org> Date: Wed, 17 Jun 2020 21:41:43 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2020 21:41:43 -0000 https://gcc.gnu.org/g:f094665d465cdf8903797cc58bea13007e588616 commit f094665d465cdf8903797cc58bea13007e588616 Author: Jonathan Wakely Date: Thu May 21 07:32:15 2020 +0100 libstdc++: Avoid constraint recursion with iterator_traits (PR 93983) Checking whether a filesystem::path constructor argument is an iterator requires instantiating std::iterator_traits. In C++20 that checks for satisfaction of std::iterator_traits constraints, which checks if the type is copyable, which can end up recursing back to the path constructor. The fix in LWG 3420 is to reorder the cpp17-iterator concept's constraints to check if the type looks vaguely like an iterator before checking copyable. That avoids the recursion for types which definitely aren't iterators, but isn't foolproof. PR libstdc++/93983 * include/bits/iterator_concepts.h (__detail::__cpp17_iterator): Reorder constraints to avoid recursion when constructors use iterator_traits (LWG 3420). * testsuite/24_iterators/customization_points/lwg3420.cc: New test. Diff: --- libstdc++-v3/ChangeLog | 6 +++ libstdc++-v3/include/bits/iterator_concepts.h | 10 +++-- .../24_iterators/customization_points/lwg3420.cc | 43 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 65039d20b9e..95c15977796 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,11 @@ 2020-05-21 Jonathan Wakely + PR libstdc++/93983 + * include/bits/iterator_concepts.h (__detail::__cpp17_iterator): + Reorder constraints to avoid recursion when constructors use + iterator_traits (LWG 3420). + * testsuite/24_iterators/customization_points/lwg3420.cc: New test. + * include/experimental/socket (basic_socket::is_open() (basic_socket_acceptor::is_open()): Use _GLIBCXX_NODISCARD macro. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index e221ec70367..31b58408fe9 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -249,14 +249,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3420. cpp17-iterator should check [type] looks like an iterator first template - concept __cpp17_iterator = copyable<_Iter> - && requires(_Iter __it) + concept __cpp17_iterator = requires(_Iter __it) { { *__it } -> __can_reference; { ++__it } -> same_as<_Iter&>; { *__it++ } -> __can_reference; - }; + } && copyable<_Iter>; template concept __cpp17_input_iterator = __cpp17_iterator<_Iter> @@ -269,7 +270,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename indirectly_readable_traits<_Iter>::value_type&>; typename common_reference_t::value_type&>; - requires signed_integral::difference_type>; + requires signed_integral< + typename incrementable_traits<_Iter>::difference_type>; }; template diff --git a/libstdc++-v3/testsuite/24_iterators/customization_points/lwg3420.cc b/libstdc++-v3/testsuite/24_iterators/customization_points/lwg3420.cc new file mode 100644 index 00000000000..72289a995fc --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/customization_points/lwg3420.cc @@ -0,0 +1,43 @@ +// 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// PR libstdc++/93983 + +// LWG 3420. +// cpp17-iterator should check that the type looks like an iterator first + +#include +#include +#include + +struct Foo +{ + Foo(const std::filesystem::path& p); +}; + +static_assert(std::copyable); + +struct X +{ + template::iterator_category> + X(const T&); +}; + +static_assert(std::copyable);