[Boost-bugs] [Boost C++ Libraries] #11835: boost::has_trivial_copy is incorrect on Clang

Subject: [Boost-bugs] [Boost C++ Libraries] #11835: boost::has_trivial_copy is incorrect on Clang
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-12-09 09:26:39


#11835: boost::has_trivial_copy is incorrect on Clang
-------------------------------------------------+-------------------------
 Reporter: joseph.thomson@… | Owner: johnmaddock
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: type_traits
  Version: Boost 1.59.0 | Severity: Problem
 Keywords: has_trivial_copy clang memcpy |
  is_trivially_copyable |
-------------------------------------------------+-------------------------
 Currently, `boost::has_trivial_copy<T>::value` is false when `T` has a
 trivial copy constructor, but is uncopyable. For example, the following
 type, despite having a trivial copy constructor, will report false:

 {{{
 struct T {
     T(T const&) = delete;
 }
 }}}

 The offending code seems to be:

 {{{
 template <typename T>
 struct has_trivial_copy_impl
 {
 #ifdef BOOST_HAS_TRIVIAL_COPY
 # ifdef __clang__
    BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T) &&
 boost::is_copy_constructible<T>::value);
 # else
    BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T));
 # endif
 #else
    BOOST_STATIC_CONSTANT(bool, value =
       (::boost::type_traits::ice_and<
          ::boost::is_pod<T>::value,
          ::boost::type_traits::ice_not< ::boost::is_volatile<T>::value
>::value
>::value));
 #endif
 };
 }}}

 This fix was applied for Clang for the following ticket:

 https://svn.boost.org/trac/boost/ticket/10389

 The fix actually broke the behaviour of `boost::has_trivial_copy` in
 Clang, to make it match the broken behaviour in GCC 4.8 and VC++. The bug
 was actually in Boost.Container, not Boost.TypeTraits, but that bug has
 now been fixed (Boost.Container no longer depends on Boost.TypeTraits).
 GCC actually fixed its intrinsic `__has_trivial_copy` in GCC 4.9, so
 `boost::has_trivial_copy` works correctly in the latest GCC versions. It's
 still broken on VC++ because of its faulty implementation of
 `__has_trivial_copy`, though it seems probable that there is no possible
 workaround.

 But I digress. `__has_trivial_copy` works on Clang, but the "fix" in Boost
 breaks `boost::has_trivial_copy`. Note that `boost::has_trivial_assign`,
 `boost::has_trivial_move_constructor` and `boost::has_trivial_move_assign`
 appear to be okay.

 And one final thought: `boost::has_trivial_copy` is not really useful for
 anything except implementing higher-level type-traits like
 `std::is_trivially_copyable` (which essentially says whether a type can be
 safely `memcpy`'d -- a copy optimization).
 `std::has_trivial_copy_constructor` does not exist, probably for this
 reason. In my opinion, it would be better for `boost::has_trivial_copy` to
 not exist in the public API, instead replacing it with a
 `boost::is_trivially_copyable`.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11835>
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:19 UTC