diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2011-09-27 02:39:34 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2011-09-27 02:39:34 +0000 |
commit | a7cee01d32cdbe912b32ad113b569b39a0e95445 (patch) | |
tree | b6525343983bf3112c8c0936acc632df1f36f60b | |
parent | b92edfe52d92baaf258a9d3234a964411a2b94b7 (diff) | |
download | gcc-a7cee01d32cdbe912b32ad113b569b39a0e95445.zip gcc-a7cee01d32cdbe912b32ad113b569b39a0e95445.tar.gz gcc-a7cee01d32cdbe912b32ad113b569b39a0e95445.tar.bz2 |
re PR libstdc++/50529 ([C++0x] std::vector::erase invokes undefined behavior with empty range)
2011-09-26 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/50529
* include/bits/vector.tcc (vector<>::erase(iterator, iterator)):
Fix to do nothing if the range is empty.
* include/bits/stl_bvector.h: Likewise.
* include/bits/deque.tcc: Likewise.
* include/debug/vector: Adjust.
* include/debug/deque: Likewise.
* testsuite/23_containers/vector/modifiers/erase/50529.cc: New.
* testsuite/23_containers/deque/modifiers/erase/50529.cc: Likewise.
* testsuite/23_containers/deque/modifiers/erase/3.cc: Adjust.
From-SVN: r179234
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/deque.tcc | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_bvector.h | 3 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/vector.tcc | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/deque | 6 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/vector | 15 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc | 6 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/50529.cc | 38 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/modifiers/erase/50529.cc | 38 |
9 files changed, 119 insertions, 13 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 05f7ef2..140bdb1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2011-09-26 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/50529 + * include/bits/vector.tcc (vector<>::erase(iterator, iterator)): + Fix to do nothing if the range is empty. + * include/bits/stl_bvector.h: Likewise. + * include/bits/deque.tcc: Likewise. + * include/debug/vector: Adjust. + * include/debug/deque: Likewise. + * testsuite/23_containers/vector/modifiers/erase/50529.cc: New. + * testsuite/23_containers/deque/modifiers/erase/50529.cc: Likewise. + * testsuite/23_containers/deque/modifiers/erase/3.cc: Adjust. + 2011-09-25 Benjamin Kosnik <bkoz@redhat.com Jonathan Wakely <jwakely.gcc@gmail.com> diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index fab7915..5b56875 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -218,7 +218,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque<_Tp, _Alloc>:: erase(iterator __first, iterator __last) { - if (__first == begin() && __last == end()) + if (__first == __last) + return __first; + else if (__first == begin() && __last == end()) { clear(); return end(); diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 22443f4..bddecb0 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -838,7 +838,8 @@ template<typename _Alloc> iterator erase(iterator __first, iterator __last) { - _M_erase_at_end(std::copy(__last, end(), __first)); + if (__first != __last) + _M_erase_at_end(std::copy(__last, end(), __first)); return __first; } diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index ba98c7c..b746842 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -147,9 +147,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: erase(iterator __first, iterator __last) { - if (__last != end()) - _GLIBCXX_MOVE3(__last, end(), __first); - _M_erase_at_end(__first.base() + (end() - __last)); + if (__first != __last) + { + if (__last != end()) + _GLIBCXX_MOVE3(__last, end(), __first); + _M_erase_at_end(__first.base() + (end() - __last)); + } return __first; } diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 08c1cdf..2bce992 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -464,7 +464,11 @@ namespace __debug // _GLIBCXX_RESOLVE_LIB_DEFECTS // 151. can't currently clear() empty container __glibcxx_check_erase_range(__first, __last); - if (__first.base() == _Base::begin() || __last.base() == _Base::end()) + + if (__first == __last) + return __first; + else if (__first.base() == _Base::begin() + || __last.base() == _Base::end()) { this->_M_detach_singular(); for (_Base_iterator __position = __first.base(); diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 9d68d007..865c275 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -499,11 +499,16 @@ namespace __debug // 151. can't currently clear() empty container __glibcxx_check_erase_range(__first, __last); - difference_type __offset = __first.base() - _Base::begin(); - _Base_iterator __res = _Base::erase(__first.base(), - __last.base()); - this->_M_invalidate_after_nth(__offset); - return iterator(__res, this); + if (__first != __last) + { + difference_type __offset = __first.base() - _Base::begin(); + _Base_iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_after_nth(__offset); + return iterator(__res, this); + } + else + return __first; } void diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc index 34d0f74..79a046e 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2009, 2010, 2011 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 @@ -31,7 +31,9 @@ void erase(size_t num_elm, size_t elm_strt, size_t elm_end) x.erase(x.begin() + elm_strt, x.begin() + elm_end); - const size_t min_num_cpy = std::min(elm_strt, num_elm - elm_end); + const size_t min_num_cpy + = elm_strt == elm_end ? 0 : std::min(elm_strt, num_elm - elm_end); + VERIFY( assignment_operator::count() == min_num_cpy ); } diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/50529.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/50529.cc new file mode 100644 index 0000000..f534758 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/50529.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++0x" } + +// 2011-09-26 Paolo Carlini <paolo.carlini@oracle.com> + +// Copyright (C) 2011 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/>. + +#include <deque> +#include <testsuite_rvalref.h> + +// libstdc++/50529 +void test01() +{ + std::deque<__gnu_test::rvalstruct> d(10); + + for (auto it = d.begin(); it != d.end(); ++it) + d.erase(it, it); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/erase/50529.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/erase/50529.cc new file mode 100644 index 0000000..d76bed5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/erase/50529.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++0x" } + +// 2011-09-26 Paolo Carlini <paolo.carlini@oracle.com> + +// Copyright (C) 2011 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/>. + +#include <vector> +#include <testsuite_rvalref.h> + +// libstdc++/50529 +void test01() +{ + std::vector<__gnu_test::rvalstruct> v(10); + + for (auto it = v.begin(); it != v.end(); ++it) + v.erase(it, it); +} + +int main() +{ + test01(); + return 0; +} |