[gcc(refs/vendors/ARM/heads/arm-perf-staging)] libstdc++: Avoid constraint recursion with iterator_traits (PR 93983)

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 15:14:37 GMT 2020


https://gcc.gnu.org/g:566ba72126288272607374a32ac646dcd36fe584

commit 566ba72126288272607374a32ac646dcd36fe584
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 21 07:47:17 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.
    
    Backport from mainline
    2020-05-21  Jonathan Wakely  <jwakely@redhat.com>
    
            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                             | 11 ++++++
 libstdc++-v3/include/bits/iterator_concepts.h      | 10 +++--
 .../24_iterators/customization_points/lwg3420.cc   | 43 ++++++++++++++++++++++
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d9c2ecf1ed4..b53ddacb574 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2020-05-21  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backport from mainline
+	2020-05-21  Jonathan Wakely  <jwakely@redhat.com>
+
+	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.
+
 2020-05-12  Jonathan Wakely  <jwakely@redhat.com>
 
 	Backport from mainline
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index c5b6247cde7..2721240e383 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<typename _Iter>
-      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<typename _Iter>
       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<decltype(*__it++)&&,
 		   typename indirectly_readable_traits<_Iter>::value_type&>;
-	  requires signed_integral<typename incrementable_traits<_Iter>::difference_type>;
+	  requires signed_integral<
+	    typename incrementable_traits<_Iter>::difference_type>;
 	};
 
     template<typename _Iter>
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
+// <http://www.gnu.org/licenses/>.
+
+// { 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 <filesystem>
+#include <iterator>
+#include <concepts>
+
+struct Foo
+{
+  Foo(const std::filesystem::path& p);
+};
+
+static_assert(std::copyable<Foo>);
+
+struct X
+{
+  template<typename T, typename = std::iterator_traits<T>::iterator_category>
+    X(const T&);
+};
+
+static_assert(std::copyable<X>);


More information about the Libstdc++-cvs mailing list