summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-10-11 21:13:44 +0000
committerEric Fiselier <eric@efcs.ca>2016-10-11 21:13:44 +0000
commite778d10c0fc39d4e52dcd54dc9c97d20b0310404 (patch)
treedbdd13ed383057f5fa9c49e54e3a06b6a54165c0
parent7d84aff200a3d72108e0e0011116dbcffce9a6e2 (diff)
downloadbcm5719-llvm-e778d10c0fc39d4e52dcd54dc9c97d20b0310404.tar.gz
bcm5719-llvm-e778d10c0fc39d4e52dcd54dc9c97d20b0310404.zip
Fix incorrect exception handling behavior in the uninitialized algorithms
llvm-svn: 283941
-rw-r--r--libcxx/include/memory139
-rw-r--r--libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp6
-rw-r--r--libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp8
6 files changed, 114 insertions, 63 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory
index d5b39cbae6c..69068f34daa 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -3709,21 +3709,63 @@ uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void destroy_at(_Tp* __loc) {
+ _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+ __loc->~_Tp();
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void destroy(_ForwardIterator __first, _ForwardIterator __last) {
+ for (; __first != __last; ++__first)
+ _VSTD::destroy_at(_VSTD::addressof(*__first));
+}
+
+template <class _ForwardIterator, class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
+ for (; __n > 0; (void)++__first, --__n)
+ _VSTD::destroy_at(_VSTD::addressof(*__first));
+ 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;
- for (; __first != __last; ++__first)
- ::new((void*)_VSTD::addressof(*__first)) _Vt;
+ 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;
- for (; __n > 0; (void)++__first, --__n)
- ::new((void*)_VSTD::addressof(*__first)) _Vt;
- return __first;
+ 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
}
@@ -3731,60 +3773,79 @@ 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();
+ 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;
- for (; __n > 0; (void)++__first, --__n)
- ::new((void*)_VSTD::addressof(*__first)) _Vt();
- return __first;
+ 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 __res) {
+_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_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;
+ 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 __res) {
+uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_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) {
- _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
- __loc->~_Tp();
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void destroy(_ForwardIterator __first, _ForwardIterator __last) {
- for (; __first != __last; ++__first)
- _VSTD::destroy_at(_VSTD::addressof(*__first));
+ 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
}
-template <class _ForwardIterator, class _Size>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
- for (; __n > 0; (void)++__first, --__n)
- _VSTD::destroy_at(_VSTD::addressof(*__first));
- return __first;
-}
#endif // _LIBCPP_STD_VER > 14
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp
index cd57769df2e..533d516707e 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp
@@ -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
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp
index bfb74b99ecd..f22a74f1f83 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp
@@ -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
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
index befe30a6c03..c2d860694a7 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
@@ -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
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
index 6149838218e..d7a9542b4c2 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
@@ -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
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
index cf6af7472b8..f27e5726135 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
@@ -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
}
OpenPOWER on IntegriCloud