mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 03:32:35 +08:00
Fix incorrect exception handling behavior in the uninitialized algorithms
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@283941 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
171
include/memory
171
include/memory
@@ -3709,61 +3709,6 @@ uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
|
||||
template <class _ForwardIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
for (; __first != __last; ++__first)
|
||||
::new((void*)_VSTD::addressof(*__first)) _Vt;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Size>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
for (; __n > 0; (void)++__first, --__n)
|
||||
::new((void*)_VSTD::addressof(*__first)) _Vt;
|
||||
return __first;
|
||||
}
|
||||
|
||||
|
||||
template <class _ForwardIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
for (; __first != __last; ++__first)
|
||||
::new((void*)_VSTD::addressof(*__first)) _Vt();
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Size>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
for (; __n > 0; (void)++__first, --__n)
|
||||
::new((void*)_VSTD::addressof(*__first)) _Vt();
|
||||
return __first;
|
||||
}
|
||||
|
||||
|
||||
template <class _InputIt, class _ForwardIt>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __res) {
|
||||
using _Vt = typename iterator_traits<_ForwardIt>::value_type;
|
||||
for (; __first != __last; (void)++__res, ++__first)
|
||||
::new((void*)_VSTD::addressof(*__res)) _Vt(std::move(*__first));
|
||||
return __res;
|
||||
}
|
||||
|
||||
template <class _InputIt, class _Size, class _ForwardIt>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
pair<_InputIt, _ForwardIt>
|
||||
uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __res) {
|
||||
using _Vt = typename iterator_traits<_ForwardIt>::value_type;
|
||||
for (; __n > 0; ++__res, (void)++__first, --__n)
|
||||
::new((void*)_VSTD::addressof(*__res)) _Vt(std::move(*__first));
|
||||
return {__first, __res};
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void destroy_at(_Tp* __loc) {
|
||||
@@ -3786,6 +3731,122 @@ _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
auto __idx = __first;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __idx != __last; ++__idx)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Size>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
auto __idx = __first;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __n > 0; (void)++__idx, --__n)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt;
|
||||
return __idx;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class _ForwardIterator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
auto __idx = __first;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __idx != __last; ++__idx)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt();
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Size>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
|
||||
using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
|
||||
auto __idx = __first;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __n > 0; (void)++__idx, --__n)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt();
|
||||
return __idx;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class _InputIt, class _ForwardIt>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
|
||||
using _Vt = typename iterator_traits<_ForwardIt>::value_type;
|
||||
auto __idx = __first_res;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __first != __last; (void)++__idx, ++__first)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
|
||||
return __idx;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first_res, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class _InputIt, class _Size, class _ForwardIt>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
pair<_InputIt, _ForwardIt>
|
||||
uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
|
||||
using _Vt = typename iterator_traits<_ForwardIt>::value_type;
|
||||
auto __idx = __first_res;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
for (; __n > 0; ++__idx, (void)++__first, --__n)
|
||||
::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
|
||||
return {__first, __idx};
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
_VSTD::destroy(__first_res, __idx);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
|
||||
|
@@ -47,7 +47,7 @@ struct ThrowsCounted {
|
||||
++count;
|
||||
}
|
||||
ThrowsCounted(ThrowsCounted const&) { assert(false); }
|
||||
~ThrowsCounted() { --count; }
|
||||
~ThrowsCounted() { assert(count > 0); --count; }
|
||||
friend void operator&(ThrowsCounted) = delete;
|
||||
};
|
||||
int ThrowsCounted::count = 0;
|
||||
@@ -67,10 +67,8 @@ void test_ctor_throws()
|
||||
std::uninitialized_default_construct(It(p), It(p+N));
|
||||
assert(false);
|
||||
} catch (...) {}
|
||||
assert(ThrowsCounted::count == 3);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
std::destroy(p, p+3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ struct Counted {
|
||||
static void reset() { count = constructed = 0; }
|
||||
explicit Counted() { ++count; ++constructed; }
|
||||
Counted(Counted const&) { assert(false); }
|
||||
~Counted() { --count; }
|
||||
~Counted() { assert(count > 0); --count; }
|
||||
friend void operator&(Counted) = delete;
|
||||
};
|
||||
int Counted::count = 0;
|
||||
@@ -47,7 +47,7 @@ struct ThrowsCounted {
|
||||
++count;
|
||||
}
|
||||
ThrowsCounted(ThrowsCounted const&) { assert(false); }
|
||||
~ThrowsCounted() { --count; }
|
||||
~ThrowsCounted() { assert(count > 0); --count; }
|
||||
friend void operator&(ThrowsCounted) = delete;
|
||||
};
|
||||
int ThrowsCounted::count = 0;
|
||||
@@ -66,10 +66,8 @@ void test_ctor_throws()
|
||||
std::uninitialized_default_construct_n(It(p), N);
|
||||
assert(false);
|
||||
} catch (...) {}
|
||||
assert(ThrowsCounted::count == 3);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
std::destroy(p, p+3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ struct Counted {
|
||||
static void reset() { count = constructed = 0; }
|
||||
explicit Counted() { ++count; ++constructed; }
|
||||
Counted(Counted const&) { assert(false); }
|
||||
~Counted() { --count; }
|
||||
~Counted() { assert(count > 0); --count; }
|
||||
friend void operator&(Counted) = delete;
|
||||
};
|
||||
int Counted::count = 0;
|
||||
@@ -47,7 +47,7 @@ struct ThrowsCounted {
|
||||
++count;
|
||||
}
|
||||
ThrowsCounted(ThrowsCounted const&) { assert(false); }
|
||||
~ThrowsCounted() { --count; }
|
||||
~ThrowsCounted() { assert(count > 0); --count; }
|
||||
friend void operator&(ThrowsCounted) = delete;
|
||||
};
|
||||
int ThrowsCounted::count = 0;
|
||||
@@ -66,10 +66,8 @@ void test_ctor_throws()
|
||||
std::uninitialized_value_construct(It(p), It(p+N));
|
||||
assert(false);
|
||||
} catch (...) {}
|
||||
assert(ThrowsCounted::count == 3);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
std::destroy(p, p+3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ struct Counted {
|
||||
static void reset() { count = constructed = 0; }
|
||||
explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; }
|
||||
Counted(Counted const&) { assert(false); }
|
||||
~Counted() { --count; }
|
||||
~Counted() { assert(count > 0); --count; }
|
||||
friend void operator&(Counted) = delete;
|
||||
int value;
|
||||
};
|
||||
@@ -48,7 +48,7 @@ struct ThrowsCounted {
|
||||
x = 0;
|
||||
}
|
||||
ThrowsCounted(ThrowsCounted const&) { assert(false); }
|
||||
~ThrowsCounted() { --count; }
|
||||
~ThrowsCounted() { assert(count > 0); --count; }
|
||||
friend void operator&(ThrowsCounted) = delete;
|
||||
};
|
||||
int ThrowsCounted::count = 0;
|
||||
@@ -68,15 +68,13 @@ void test_ctor_throws()
|
||||
std::uninitialized_move(values, values + N, It(p));
|
||||
assert(false);
|
||||
} catch (...) {}
|
||||
assert(ThrowsCounted::count == 3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
assert(values[0] == 0);
|
||||
assert(values[1] == 0);
|
||||
assert(values[2] == 0);
|
||||
assert(values[3] == 4);
|
||||
assert(values[4] == 5);
|
||||
std::destroy(p, p+3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ struct Counted {
|
||||
static void reset() { count = constructed = 0; }
|
||||
explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; }
|
||||
Counted(Counted const&) { assert(false); }
|
||||
~Counted() { --count; }
|
||||
~Counted() { assert(count > 0); --count; }
|
||||
friend void operator&(Counted) = delete;
|
||||
int value;
|
||||
};
|
||||
@@ -48,7 +48,7 @@ struct ThrowsCounted {
|
||||
x = 0;
|
||||
}
|
||||
ThrowsCounted(ThrowsCounted const&) { assert(false); }
|
||||
~ThrowsCounted() { --count; }
|
||||
~ThrowsCounted() { assert(count > 0); --count; }
|
||||
friend void operator&(ThrowsCounted) = delete;
|
||||
};
|
||||
int ThrowsCounted::count = 0;
|
||||
@@ -68,15 +68,13 @@ void test_ctor_throws()
|
||||
std::uninitialized_move_n(values, N, It(p));
|
||||
assert(false);
|
||||
} catch (...) {}
|
||||
assert(ThrowsCounted::count == 3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
assert(ThrowsCounted::constructed == 4); // forth construction throws
|
||||
assert(values[0] == 0);
|
||||
assert(values[1] == 0);
|
||||
assert(values[2] == 0);
|
||||
assert(values[3] == 4);
|
||||
assert(values[4] == 5);
|
||||
std::destroy(p, p+3);
|
||||
assert(ThrowsCounted::count == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user