PR libstdc++/86292 fix exception safety of std::vector<InputIterator> constructor
PR libstdc++/86292 * include/bits/stl_vector.h (vector::_M_range_initialize<InputIter>): Add try-catch block. * testsuite/23_containers/vector/cons/86292.cc: New. From-SVN: r262029
This commit is contained in:
parent
b03f3a94e6
commit
3685dcd7fb
|
@ -1,5 +1,10 @@
|
|||
2018-06-25 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/86292
|
||||
* include/bits/stl_vector.h (vector::_M_range_initialize<InputIter>):
|
||||
Add try-catch block.
|
||||
* testsuite/23_containers/vector/cons/86292.cc: New.
|
||||
|
||||
* doc/xml/manual/status_cxx2017.xml: Document N4531 status.
|
||||
|
||||
* include/experimental/algorithm (sample, shuffle): Add new overloads
|
||||
|
|
|
@ -1440,22 +1440,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
// Called by the second initialize_dispatch above
|
||||
template<typename _InputIterator>
|
||||
void
|
||||
_M_range_initialize(_InputIterator __first,
|
||||
_InputIterator __last, std::input_iterator_tag)
|
||||
_M_range_initialize(_InputIterator __first, _InputIterator __last,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
__try {
|
||||
for (; __first != __last; ++__first)
|
||||
#if __cplusplus >= 201103L
|
||||
emplace_back(*__first);
|
||||
#else
|
||||
push_back(*__first);
|
||||
#endif
|
||||
} __catch(...) {
|
||||
clear();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
|
||||
// Called by the second initialize_dispatch above
|
||||
template<typename _ForwardIterator>
|
||||
void
|
||||
_M_range_initialize(_ForwardIterator __first,
|
||||
_ForwardIterator __last, std::forward_iterator_tag)
|
||||
_M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
|
||||
std::forward_iterator_tag)
|
||||
{
|
||||
const size_type __n = std::distance(__first, __last);
|
||||
this->_M_impl._M_start = this->_M_allocate(__n);
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// 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/>.
|
||||
|
||||
// { dg-do run }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
struct X
|
||||
{
|
||||
X() { ++count; }
|
||||
X(const X&) { if (++copies >= max_copies) throw 1; ++count; }
|
||||
~X() { --count; }
|
||||
|
||||
static int count;
|
||||
static int copies;
|
||||
static int max_copies;
|
||||
};
|
||||
|
||||
int X::count = 0;
|
||||
int X::copies = 0;
|
||||
int X::max_copies = 0;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
X x[3];
|
||||
const int count = X::count;
|
||||
X::max_copies = 2;
|
||||
__gnu_test::test_container<const X, __gnu_test::input_iterator_wrapper>
|
||||
x_input(x, x+3);
|
||||
bool caught = false;
|
||||
try
|
||||
{
|
||||
std::vector<X> v(x_input.begin(), x_input.end());
|
||||
}
|
||||
catch(int)
|
||||
{
|
||||
caught = true;
|
||||
}
|
||||
VERIFY( caught );
|
||||
VERIFY( X::count == count );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
Loading…
Reference in New Issue