[Boost-bugs] [Boost C++ Libraries] #11229: vector incorrectly copies move-only objects using memcpy

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