2018-06-13 François Dumont <fdumont@gcc.gnu.org>
+ * include/debug/helper_functions.h
+ (__gnu_debug::_Safe_iterator<>): Add declaration.
+ (__can_advance(_Ite, _Size)): New.
+ (__can_advance(const _Safe_iterator<>&, _Size)): Overload declaration.
+ * include/debug/functions.h
+ (__gnu_debug::_Safe_iterator<>): Remove declaration.
+ * include/debug/stl_iterator.h
+ (__can_advance(const _Safe_iterator<>&)): New definition.
+ * include/debug/stl_iterator.h
+ (__can_advance(const std::reverse_iterator<>&, _Size)): New.
+ (__can_advance(const std::move_iterator<>&, _Size)): New.
+ * include/debug/macros.h (__glibcxx_check_can_increment): New.
+ * include/debug/debug.h (__glibcxx_requires_can_increment): New.
+ * include/bits/stl_algobase.h (fill_n): Use latter.
+ * testsuite/25_algorithms/fill_n/2.cc: New.
+ * testsuite/25_algorithms/fill_n/debug/1_neg.cc: New.
+ * testsuite/25_algorithms/fill_n/debug/2_neg.cc: New.
+ * testsuite/25_algorithms/fill_n/debug/3_neg.cc: New.
+ * testsuite/25_algorithms/fill_n/debug/4_neg.cc: New.
+
* include/debug/debug.h (__glibcxx_requires_can_increment_range): New.
(__glibcxx_requires_can_decrement_range): New.
{
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>)
+ __glibcxx_requires_can_increment(__first, __n);
return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value));
}
# define __glibcxx_requires_cond(_Cond,_Msg)
# define __glibcxx_requires_valid_range(_First,_Last)
+# define __glibcxx_requires_can_increment(_First,_Size)
# define __glibcxx_requires_can_increment_range(_First1,_Last1,_First2)
# define __glibcxx_requires_can_decrement_range(_First1,_Last1,_First2)
# define __glibcxx_requires_sorted(_First,_Last)
# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
# define __glibcxx_requires_valid_range(_First,_Last) \
__glibcxx_check_valid_range(_First,_Last)
+# define __glibcxx_requires_can_increment(_First,_Size) \
+ __glibcxx_check_can_increment(_First,_Size)
# define __glibcxx_requires_can_increment_range(_First1,_Last1,_First2) \
__glibcxx_check_can_increment_range(_First1,_Last1,_First2)
# define __glibcxx_requires_can_decrement_range(_First1,_Last1,_First2) \
namespace __gnu_debug
{
- template<typename _Iterator, typename _Sequence>
- class _Safe_iterator;
-
template<typename _Sequence>
struct _Insert_range_from_self_is_safe
{ enum { __value = 0 }; };
namespace __gnu_debug
{
+ template<typename _Iterator, typename _Sequence>
+ class _Safe_iterator;
+
/** The precision to which we can calculate the distance between
* two iterators.
*/
return __valid_range(__first, __last, __dist);
}
+ // Fallback method, always ok.
+ template<typename _InputIterator, typename _Size>
+ inline bool
+ __can_advance(_InputIterator, _Size)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence, typename _Size>
+ bool
+ __can_advance(const _Safe_iterator<_Iterator, _Sequence>&, _Size);
+
#if __cplusplus < 201103L
// Helper struct to detect random access safe iterators.
template<typename _Iterator>
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last))
+// Verify that [_First, _First + _Size) forms a valid range.
+#define __glibcxx_check_can_increment(_First,_Size) \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__can_advance(_First, _Size), \
+ _M_message(__gnu_debug::__msg_iter_subscript_oob) \
+ ._M_iterator(_First, #_First) \
+ ._M_integer(_Size, #_Size))
+
#define __glibcxx_check_can_increment_range(_First1,_Last1,_First2) \
do \
{ \
return __res;
}
+ template<typename _Iterator, typename _Sequence, typename _Size>
+ inline bool
+ __can_advance(const _Safe_iterator<_Iterator, _Sequence>& __it, _Size __n)
+ { return __it._M_can_advance(__n); }
+
#if __cplusplus < 201103L
template<typename _Iterator, typename _Sequence>
struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
const std::reverse_iterator<_Iterator>& __last)
{ return __get_distance(__last.base(), __first.base()); }
+ template<typename _Iterator, typename _Size>
+ inline bool
+ __can_advance(const std::reverse_iterator<_Iterator>& __it, _Size __n)
+ { return __can_advance(__it.base(), -__n); }
+
#if __cplusplus < 201103L
template<typename _Iterator>
struct __is_safe_random_iterator<std::reverse_iterator<_Iterator> >
const std::move_iterator<_Iterator>& __last)
{ return __get_distance(__first.base(), __last.base()); }
+ template<typename _Iterator, typename _Size>
+ inline bool
+ __can_advance(const std::move_iterator<_Iterator>& __it, _Size __n)
+ { return __can_advance(__it.base(), __n); }
+
template<typename _Iterator>
inline auto
__unsafe(const std::move_iterator<_Iterator>& __it)
--- /dev/null
+// Copyright (C) 2018 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/>.
+
+// 25.2.5 [lib.alg.fill] Fill_n.
+
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+#include <vector>
+
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::vector<int> ref;
+ ref.push_back(1);
+ ref.push_back(2);
+
+ std::vector<std::vector<int>> vvect;
+ vvect.push_back(std::vector<int>());
+ vvect.push_back(std::vector<int>());
+
+ VERIFY( std::fill_n(vvect.begin(), 2, ref) == vvect.end() );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2018 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/>.
+
+// 25.2.5 [lib.alg.fill] Fill_n.
+
+// { dg-do run { xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+#include <vector>
+
+void
+test01()
+{
+ std::vector<int> vect;
+ vect.push_back(1);
+ std::fill_n(vect.begin(), 2, 0);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2018 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/>.
+
+// 25.2.5 [lib.alg.fill] Fill_n.
+
+// { dg-do run { xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+#include <vector>
+
+void
+test01()
+{
+ std::vector<int> vect;
+ vect.push_back(1);
+ std::fill_n(vect.rbegin(), 2, 0);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2018 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/>.
+
+// 25.2.5 [lib.alg.fill] Fill_n.
+
+// { dg-do run { xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+#include <list>
+
+void
+test01()
+{
+ std::list<int> l;
+ l.push_back(1);
+ std::fill_n(l.begin(), 2, 0);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2018 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/>.
+
+// 25.2.5 [lib.alg.fill] Fill_n.
+
+// { dg-do run { xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+#include <list>
+
+void
+test01()
+{
+ std::list<int> l;
+ l.push_back(1);
+ l.push_back(2);
+
+ std::list<int>::iterator it = l.begin();
+ ++it;
+ std::fill_n(it, 2, 0);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}