aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-09-27 02:39:34 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-09-27 02:39:34 +0000
commita7cee01d32cdbe912b32ad113b569b39a0e95445 (patch)
treeb6525343983bf3112c8c0936acc632df1f36f60b
parentb92edfe52d92baaf258a9d3234a964411a2b94b7 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/deque.tcc4
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h3
-rw-r--r--libstdc++-v3/include/bits/vector.tcc9
-rw-r--r--libstdc++-v3/include/debug/deque6
-rw-r--r--libstdc++-v3/include/debug/vector15
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/50529.cc38
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/erase/50529.cc38
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;
+}