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:
Jonathan Wakely 2018-06-25 17:46:33 +01:00 committed by Jonathan Wakely
parent b03f3a94e6
commit 3685dcd7fb
3 changed files with 81 additions and 7 deletions

View File

@ -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

View File

@ -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)
{
for (; __first != __last; ++__first)
__try {
for (; __first != __last; ++__first)
#if __cplusplus >= 201103L
emplace_back(*__first);
emplace_back(*__first);
#else
push_back(*__first);
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);

View File

@ -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();
}