PR libstdc++/90920 restore previous checks for empty ranges
The change in r263433 broke the contract of the __rotate functions, by no longer accepting empty ranges. That means that callers which inlined the old version of std::rotate (without checks) that end up linking to a new definition of std::__rotate (also without checks) could perform a divide by zero and crash. This restores the old contract of the __rotate overloads. PR libstdc++/90920 partially revert r263433 * include/bits/stl_algo.h (__rotate): Restore checks for empty ranges. (rotate): Remove checks. * testsuite/25_algorithms/rotate/90920.cc: New test. From-SVN: r272489
This commit is contained in:
parent
c6f0626b11
commit
0fd9e8482e
@ -1,5 +1,10 @@
|
||||
2019-06-19 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/90920 partially revert r263433
|
||||
* include/bits/stl_algo.h (__rotate): Restore checks for empty ranges.
|
||||
(rotate): Remove checks.
|
||||
* testsuite/25_algorithms/rotate/90920.cc: New test.
|
||||
|
||||
* include/std/numeric (reduce(Iter, Iter, T, BinOp)): Fix value
|
||||
category used in invocable check.
|
||||
(reduce(Iter, Iter, T)): Pass initial value as rvalue.
|
||||
|
@ -1251,6 +1251,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_ForwardIterator __last,
|
||||
forward_iterator_tag)
|
||||
{
|
||||
if (__first == __middle)
|
||||
return __last;
|
||||
else if (__last == __middle)
|
||||
return __first;
|
||||
|
||||
_ForwardIterator __first2 = __middle;
|
||||
do
|
||||
{
|
||||
@ -1291,6 +1296,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
|
||||
_BidirectionalIterator>)
|
||||
|
||||
if (__first == __middle)
|
||||
return __last;
|
||||
else if (__last == __middle)
|
||||
return __first;
|
||||
|
||||
std::__reverse(__first, __middle, bidirectional_iterator_tag());
|
||||
std::__reverse(__middle, __last, bidirectional_iterator_tag());
|
||||
|
||||
@ -1324,6 +1334,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
|
||||
_RandomAccessIterator>)
|
||||
|
||||
if (__first == __middle)
|
||||
return __last;
|
||||
else if (__last == __middle)
|
||||
return __first;
|
||||
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
|
||||
_Distance;
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::value_type
|
||||
@ -1425,11 +1440,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_requires_valid_range(__first, __middle);
|
||||
__glibcxx_requires_valid_range(__middle, __last);
|
||||
|
||||
if (__first == __middle)
|
||||
return __last;
|
||||
else if (__last == __middle)
|
||||
return __first;
|
||||
|
||||
return std::__rotate(__first, __middle, __last,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
|
48
libstdc++-v3/testsuite/25_algorithms/rotate/90920.cc
Normal file
48
libstdc++-v3/testsuite/25_algorithms/rotate/90920.cc
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2019 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-do run }
|
||||
|
||||
#include <algorithm>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
namespace gnu_test
|
||||
{
|
||||
// This is the definition from GCC 8.x, with no checks for first==middle
|
||||
// or middle==last.
|
||||
template<typename _ForwardIterator>
|
||||
inline _ForwardIterator
|
||||
rotate(_ForwardIterator __first, _ForwardIterator __middle,
|
||||
_ForwardIterator __last)
|
||||
{
|
||||
return std::__rotate(__first, __middle, __last,
|
||||
std::__iterator_category(__first));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
int i = 0;
|
||||
gnu_test::rotate(&i, &i, &i+1);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
Loading…
Reference in New Issue
Block a user