| commit b370e7691a680b06f3c159c6a19582adf449de90 |
| Author: Louis Dionne <ldionne@apple.com> |
| Date: Thu Sep 5 13:50:28 2019 +0000 |
| |
| [libc++] Revert "Make `vector` unconditionally move elements when exceptions are disabled." |
| |
| This reverts r370502, which broke the use case of a copy-only T (with a |
| deleted move constructor) when exceptions are disabled. Until we figure |
| out the right behavior, I'm reverting the commit. |
| |
| llvm-svn: 371068 |
| |
| diff --git a/libcxx/include/memory b/libcxx/include/memory |
| index ec1f3d91403..321d5fee12a 100644 |
| --- a/libcxx/include/memory |
| +++ b/libcxx/include/memory |
| @@ -1609,16 +1609,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| _LIBCPP_INLINE_VISIBILITY |
| static |
| void |
| - __construct_forward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) |
| + __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) |
| { |
| for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) |
| - construct(__a, _VSTD::__to_raw_pointer(__begin2), |
| -#ifdef _LIBCPP_NO_EXCEPTIONS |
| - _VSTD::move(*__begin1) |
| -#else |
| - _VSTD::move_if_noexcept(*__begin1) |
| -#endif |
| - ); |
| + construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); |
| } |
| |
| template <class _Tp> |
| @@ -1631,7 +1625,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| is_trivially_move_constructible<_Tp>::value, |
| void |
| >::type |
| - __construct_forward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) |
| + __construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) |
| { |
| ptrdiff_t _Np = __end1 - __begin1; |
| if (_Np > 0) |
| @@ -1678,18 +1672,12 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| _LIBCPP_INLINE_VISIBILITY |
| static |
| void |
| - __construct_backward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) |
| + __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) |
| { |
| while (__end1 != __begin1) |
| { |
| - construct(__a, _VSTD::__to_raw_pointer(__end2 - 1), |
| -#ifdef _LIBCPP_NO_EXCEPTIONS |
| - _VSTD::move(*--__end1) |
| -#else |
| - _VSTD::move_if_noexcept(*--__end1) |
| -#endif |
| - ); |
| - --__end2; |
| + construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1)); |
| + --__end2; |
| } |
| } |
| |
| @@ -1703,7 +1691,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| is_trivially_move_constructible<_Tp>::value, |
| void |
| >::type |
| - __construct_backward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) |
| + __construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) |
| { |
| ptrdiff_t _Np = __end1 - __begin1; |
| __end2 -= _Np; |
| diff --git a/libcxx/include/vector b/libcxx/include/vector |
| index a07243a1345..2d83484aa20 100644 |
| --- a/libcxx/include/vector |
| +++ b/libcxx/include/vector |
| @@ -948,8 +948,7 @@ void |
| vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) |
| { |
| __annotate_delete(); |
| - __alloc_traits::__construct_backward_with_exception_guarantees( |
| - this->__alloc(), this->__begin_, this->__end_, __v.__begin_); |
| + __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); |
| _VSTD::swap(this->__begin_, __v.__begin_); |
| _VSTD::swap(this->__end_, __v.__end_); |
| _VSTD::swap(this->__end_cap(), __v.__end_cap()); |
| @@ -964,10 +963,8 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a |
| { |
| __annotate_delete(); |
| pointer __r = __v.__begin_; |
| - __alloc_traits::__construct_backward_with_exception_guarantees( |
| - this->__alloc(), this->__begin_, __p, __v.__begin_); |
| - __alloc_traits::__construct_forward_with_exception_guarantees( |
| - this->__alloc(), __p, this->__end_, __v.__end_); |
| + __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_); |
| + __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_); |
| _VSTD::swap(this->__begin_, __v.__begin_); |
| _VSTD::swap(this->__end_, __v.__end_); |
| _VSTD::swap(this->__end_cap(), __v.__end_cap()); |
| diff --git a/libcxx/test/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.sh.cpp b/libcxx/test/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.sh.cpp |
| deleted file mode 100644 |
| index 1e9cbde0114..00000000000 |
| --- a/libcxx/test/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.sh.cpp |
| +++ /dev/null |
| @@ -1,57 +0,0 @@ |
| -//===----------------------------------------------------------------------===// |
| -// |
| -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| -// See https://llvm.org/LICENSE.txt for license information. |
| -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -// |
| -//===----------------------------------------------------------------------===// |
| - |
| -// RUN: %build -fno-exceptions |
| -// RUN: %run |
| - |
| -// UNSUPPORTED: c++98, c++03 |
| - |
| -// <vector> |
| - |
| -// Test that vector always moves elements when exceptions are disabled. |
| -// vector is allowed to move or copy elements while resizing, so long as |
| -// it still provides the strong exception safety guarantee. |
| - |
| -#include <vector> |
| -#include <cassert> |
| - |
| -#include "test_macros.h" |
| - |
| -#ifndef TEST_HAS_NO_EXCEPTIONS |
| -#error exceptions should be disabled. |
| -#endif |
| - |
| -bool allow_moves = false; |
| - |
| -class A { |
| -public: |
| - A() {} |
| - A(A&&) { assert(allow_moves); } |
| - explicit A(int) {} |
| - A(A const&) { assert(false); } |
| -}; |
| - |
| -int main(int, char**) { |
| - std::vector<A> v; |
| - |
| - // Create a vector containing some number of elements that will |
| - // have to be moved when it is resized. |
| - v.reserve(10); |
| - size_t old_cap = v.capacity(); |
| - for (int i = 0; i < v.capacity(); ++i) { |
| - v.emplace_back(42); |
| - } |
| - assert(v.capacity() == old_cap); |
| - assert(v.size() == v.capacity()); |
| - |
| - // The next emplace back should resize. |
| - allow_moves = true; |
| - v.emplace_back(42); |
| - |
| - return 0; |
| -} |