Subject: [Boost-bugs] [Boost C++ Libraries] #11229: vector incorrectly copies move-only objects using memcpy
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-04-23 15:55:09
#11229: vector incorrectly copies move-only objects using memcpy
------------------------------+------------------------
Reporter: joseph.thomson@⦠| Owner: igaztanaga
Type: Bugs | Status: new
Milestone: To Be Determined | Component: container
Version: Boost 1.58.0 | Severity: Problem
Keywords: |
------------------------------+------------------------
The behaviour of `__has_trivial_copy` seems to have be corrected in GCC
4.9, such that deleted copy constructors are now considered trivial. This
seems to be in-line with the C++ standard and Clang as explained in this
issue:
https://svn.boost.org/trac/boost/ticket/10389
This change seems to have exposed a bug in Boost.Container, where objects
are copied using memcpy if they have a trivial copy constructor. However,
memcpy should only be used as an optimization on trivially copyable
objects, the requirements for which include no non-trivial move
constructors or assignment operators.
Move-only classes like std::unique_ptr have trivial (but deleted) copy
constructors, but are not trivially copyable, since they define move
operations.
To fix this, I think that boost/container/details/utilities.hpp needs to
be changed. Perhaps something like this:
{{{
template <typename I, typename O>
struct is_memtransfer_copy_assignable
{
static const bool value = are_contiguous_and_same<I, O>::value &&
boost::is_copy_assignable< typename
::std::iterator_traits<I>::value_type >::value &&
boost::has_trivial_assign< typename
::std::iterator_traits<I>::value_type >::value;
};
template <typename I, typename O>
struct is_memtransfer_copy_constructible
{
static const bool value = are_contiguous_and_same<I, O>::value &&
boost::is_copy_constructible< typename
::std::iterator_traits<I>::value_type >::value &&
boost::has_trivial_copy< typename
::std::iterator_traits<I>::value_type >::value;
};
}}}
This is a check for whether the class has a trivial copy
constructor/assignment operator, which I believe should be fine.
boost::is_copy_assignable used to exist in Boost 1.58.0, but seems to have
been removed in the development trunk for some reason.
Note that _has_trivial_copy still behaves incorrectly in this circumstance
in VC++12. In fact, VC++ seems to have broken boost::is_copy_assignable
and boost::is_copy_constructible functions, as well as broken SFINAE
detection for copy/move constructors and operators. Thus, the
modification I have above will still work around this problem, but only
because all of the functions return the wrong values.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11229> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC