This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Bug libstdc++/63500] [4.9/5 Regression] bug in debug version of std::make_move_iterator?
- From: FranÃois Dumont <frs dot dumont at gmail dot com>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 14 Oct 2014 23:51:28 +0200
- Subject: [Bug libstdc++/63500] [4.9/5 Regression] bug in debug version of std::make_move_iterator?
- Authentication-results: sourceware.org; auth=none
- References: <bug-63500-19885 at http dot gcc dot gnu dot org/bugzilla/> <bug-63500-19885-6PZlFsivrJ at http dot gcc dot gnu dot org/bugzilla/>
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)));
+}