This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/63500] [4.9/5 Regression] bug in debug version of std::make_move_iterator?


Hi

Here is a proposal to fix the issue with iterators which do not expose lvalue references when dereferenced. I simply chose to detect such an issue in c++11 mode thanks to the is_lvalue_reference meta function.

2014-10-15  FranÃois Dumont  <fdumont@gcc.gnu.org>

    PR libstdc++/63500
    * include/bits/cpp_type_traits.h (__true_type): Add __value constant.
    (__false_type): Likewise.
    * include/debug/functions.h (__foreign_iterator_aux2): Do not check for
    foreign iterators if input iterators returns rvalue reference.
    * testsuite/23_containers/vector/63500.cc: New.

Tested under Linux x86_64.

FranÃois

Index: include/bits/cpp_type_traits.h
===================================================================
--- include/bits/cpp_type_traits.h	(revision 216158)
+++ include/bits/cpp_type_traits.h	(working copy)
@@ -79,9 +79,12 @@
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  struct __true_type { };
-  struct __false_type { };
+  struct __true_type
+  { enum { __value = 1 }; };
 
+  struct __false_type
+  { enum { __value = 0 }; };
+
   template<bool>
     struct __truth_type
     { typedef __false_type __type; };
Index: include/debug/functions.h
===================================================================
--- include/debug/functions.h	(revision 216158)
+++ include/debug/functions.h	(working copy)
@@ -34,7 +34,7 @@
 					  // _Iter_base
 #include <bits/cpp_type_traits.h>	  // for __is_integer
 #include <bits/move.h>                    // for __addressof and addressof
-# include <bits/stl_function.h>		  // for less
+#include <bits/stl_function.h>		  // for less
 #if __cplusplus >= 201103L
 # include <type_traits>			  // for is_lvalue_reference and __and_
 #endif
@@ -252,8 +252,21 @@
 			    const _InputIterator& __other,
 			    const _InputIterator& __other_end)
     {
+#if __cplusplus >= 201103L
+      typedef std::iterator_traits<_InputIterator> _InputIteTraits;
+      typedef typename _InputIteTraits::reference _InputIteRefType;
+#endif
       return __foreign_iterator_aux3(__it, __other, __other_end,
+#if __cplusplus < 201103L
 				     _Is_contiguous_sequence<_Sequence>());
+#else
+      typename std::conditional<
+	std::__and_<std::integral_constant<
+	  bool, _Is_contiguous_sequence<_Sequence>::__value>,
+		    std::is_lvalue_reference<_InputIteRefType> >::value,
+	std::__true_type,
+	std::__false_type>::type());
+#endif
     }
 
   /* Handle the case where we aren't really inserting a range after all */
Index: testsuite/23_containers/vector/63500.cc
===================================================================
--- testsuite/23_containers/vector/63500.cc	(revision 0)
+++ testsuite/23_containers/vector/63500.cc	(working copy)
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+
+// Copyright (C) 2014 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++11" }
+// { dg-do compile }
+
+#include <memory>
+#include <iterator>
+#include <debug/vector>
+
+class Foo
+{};
+
+void
+test01()
+{
+  __gnu_debug::vector<std::unique_ptr<Foo>> v;
+  __gnu_debug::vector<std::unique_ptr<Foo>> w;
+
+  v.insert(end(v),
+	   make_move_iterator(begin(w)),
+	   make_move_iterator(end(w)));
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]