Boost C++ Libraries: Ticket #11229: vector incorrectly copies move-only objects using memcpy https://svn.boost.org/trac10/ticket/11229 <p> The behaviour of <code>__has_trivial_copy</code> 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: </p> <p> <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/10389"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/10389</a> </p> <p> 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. </p> <p> Move-only classes like std::unique_ptr have trivial (but deleted) copy constructors, but are not trivially copyable, since they define move operations. </p> <p> To fix this, I think that boost/container/details/utilities.hpp needs to be changed. Perhaps something like this: </p> <pre class="wiki">template &lt;typename I, typename O&gt; struct is_memtransfer_copy_assignable { static const bool value = are_contiguous_and_same&lt;I, O&gt;::value &amp;&amp; boost::is_copy_assignable&lt; typename ::std::iterator_traits&lt;I&gt;::value_type &gt;::value &amp;&amp; boost::has_trivial_assign&lt; typename ::std::iterator_traits&lt;I&gt;::value_type &gt;::value; }; template &lt;typename I, typename O&gt; struct is_memtransfer_copy_constructible { static const bool value = are_contiguous_and_same&lt;I, O&gt;::value &amp;&amp; boost::is_copy_constructible&lt; typename ::std::iterator_traits&lt;I&gt;::value_type &gt;::value &amp;&amp; boost::has_trivial_copy&lt; typename ::std::iterator_traits&lt;I&gt;::value_type &gt;::value; }; </pre><p> 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. </p> <p> 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. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11229 Trac 1.4.3 anonymous Thu, 23 Apr 2015 16:43:29 GMT <link>https://svn.boost.org/trac10/ticket/11229#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:1</guid> <description> <p> To clarify, I meant that the <code>std::is_trivially_copyable</code> is broken in VC++. In fact, it is a synonym for <code>std::is_trivially_copy_constructible</code>, which is just wrong. <code>__has_trivial_copy</code> is just one requirement of both <code>std::is_trivially_copyable</code> and <code>std::is_trivially_copy_constructible</code>. That said, I haven't even looked at how <code>boost:has_trivial_copy</code> and <code>boost::has_trivial_assign</code> are implemented on VC++. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 25 Apr 2015 21:48:27 GMT</pubDate> <title>component changed https://svn.boost.org/trac10/ticket/11229#comment:2 https://svn.boost.org/trac10/ticket/11229#comment:2 <ul> <li><strong>component</strong> <span class="trac-field-old">container</span> → <span class="trac-field-new">move</span> </li> </ul> <p> Could you check please if commit SHA-1: 32f4d91cecc331f8f6ccf8e4d04041c573f1f347 </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/32f4d91cecc331f8f6ccf8e4d04041c573f1f347"><span class="icon">​</span>https://github.com/boostorg/move/commit/32f4d91cecc331f8f6ccf8e4d04041c573f1f347</a> </p> <p> solves the problem? </p> Ticket joseph.thomson@… Sun, 26 Apr 2015 00:07:23 GMT <link>https://svn.boost.org/trac10/ticket/11229#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:3</guid> <description> <p> Assuming that boost::move_detail::is_copy_constructible and boost::move_detail::is_copy_assignable work on VC++ (if the tests pass, it would seem this is the case), I still don't know if this change fixes the bug. The is_memtransfer_copy_constructible and is_memtransfer_copy_assignable functions, as far as I can tell, perform the same function as is_trivially_copy_constructible and is_trivially_copy_assignable, but they still have incorrect implementations which rely only on boost::has_trivial_copy and boost::has_trivial_assign. Surely you need to change the implementation of these functions to fix the problem? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sun, 26 Apr 2015 17:11:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:4</guid> <description> <p> The trait <em>is_memtransfer_copy_constructible</em>, at least in boost 1.58, which is the version you've reported, does not depend on boost.<a class="missing wiki">TypeTraits</a> but on Boost.Move, due to the dependency reduction work on that 1.58 version. </p> <p> In Visual 2013, <em>std::is_copy_constructible</em> wrongly returns true for types with deleted copy constructors or assignments, but fortunately the intrinsic <em>has_trivial_xxx</em> returns false. E.g: </p> <pre class="wiki"> #include &lt;boost/static_assert.hpp&gt; #include &lt;boost/move/detail/type_traits.hpp&gt; struct asdf { asdf(const asdf&amp;) = delete; asdf &amp; operator=(const asdf&amp;) = delete; }; int main() { BOOST_STATIC_ASSERT(!(__has_trivial_copy(asdf))); BOOST_STATIC_ASSERT(!(__has_trivial_assign(asdf))); BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible&lt;asdf&gt;::value)); BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable&lt;asdf&gt;::value)); } </pre><p> So <em>boost::container::vector</em> should not try to <em>memcpy</em> a type with a deleted copy/assignment . </p> <p> In any case, if a class has a public copy constructor which is trivial, and also a move constructor, boost::container is free to select the copy constructor as semantically should be consistent with the move construtor. Or are there scenarios where this could be a problem? </p> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Tue, 28 Apr 2015 21:28:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:5</guid> <description> <p> Sorry, I incorrectly assumed that trunk would contain the latest version of the source code (I was using 1.57.0, tested 1.58.0 briefly, and then looked to fix the change in trunk). </p> <p> I have just tested your update, and it seems conceptually fine. However, it fails to compile on MSVC because <code>yes_type</code> and <code>no_type</code> are undefined. Copy-paste error I think. Here is the test program I used: </p> <pre class="wiki">#include &lt;boost/container/vector.hpp&gt; #include &lt;iostream&gt; #include &lt;memory&gt; int main() { auto deleter = [](int*) { std::cout &lt;&lt; "delete\n"; }; using T = std::unique_ptr&lt;int, decltype(deleter)&gt;; std::cout &lt;&lt; std::boolalpha; std::cout &lt;&lt; "is_copy_constructible: " &lt;&lt; boost::move_detail::is_copy_constructible&lt;T&gt;::value &lt;&lt; "\n"; std::cout &lt;&lt; "is_copy_assignable: " &lt;&lt; boost::move_detail::is_copy_assignable&lt;T&gt;::value &lt;&lt; "\n"; std::cout &lt;&lt; "is_trivially_copy_constructible: " &lt;&lt; boost::move_detail::is_trivially_copy_constructible&lt;T&gt;::value &lt;&lt; "\n"; std::cout &lt;&lt; "is_trivially_copy_assignable: " &lt;&lt; boost::move_detail::is_trivially_copy_assignable&lt;T&gt;::value &lt;&lt; "\n"; boost::container::vector&lt;T&gt; values; values.push_back(T(new int(), deleter)); values.push_back(T(new int(), deleter)); } </pre><p> You assessment about the MSVC behaviour agrees with mine. Boost.Container should still work thanks to the interaction of those two bugs :) I have looked at the 2015 preview, and it seems that they have fixed <code>std::is_copy_constructible</code> and <code>std::is_copy_assignable</code>, but not <code>__has_trivial_copy</code>, <code>__has_trivial_assign</code> and <code>std::is_trivially_copyable</code>. I have filed a bug about the latter, but whether or not it is fixed should not affect Boost.Container, as the <code>std::is_copy_constructible</code> and <code>std::is_copy_assignable</code> not correctly return false in this case. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 02 Dec 2015 12:20:02 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:6</guid> <description> <p> The above discussion evolves around MSVC, but for GCC 4.9 and up Boost is currently still broken, but for that the fix that is used for Clang should be applicable as well as far as I can tell. So the resolution for <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/10389" title="#10389: Bugs: [container] Double free problem on ... (closed: fixed)">#10389</a> should also be applied for GCC 4.9 and up. </p> <p> So this simple program has different behaviour: </p> <pre class="wiki">#include &lt;memory&gt; #include &lt;boost/type_traits.hpp&gt; static_assert(!boost::has_trivial_copy&lt;std::unique_ptr&lt;int&gt;&gt;::value, "Should not be trivially copyable"); </pre><ul><li>On GCC 4.7 the assert does not fire (using Boost 1.59), i.e. it is not considered trivially copyable. </li><li>On GCC 4.9 the assert does fire </li><li>On Clang 3.7 the assert does not fire (because Boost has a workaround for clang that doesn't use the has_trivial_copy intrinsic only but also tests for copy_constructible). </li></ul><p> For 4.9 this Clang workaround should be used as well in my opinion. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 02 Dec 2015 12:43:14 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:7</guid> <description> <p> Note that more recent GCC versions have <span class="underline">is_trivially_copyable as an intrinsic, which correctly marks a unique_ptr as not being trivially copyable (the difference with </span>has_trivial_cop) seems to be that the newer intrinsic does take the requirement of a non-trivial destructor into account). </p> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Wed, 02 Dec 2015 13:35:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11229#comment:7" title="Comment 7">anonymous</a>: </p> <blockquote class="citation"> <p> Note that more recent GCC versions have <code>__is_trivially_copyable</code> as an intrinsic, which correctly marks a unique_ptr as not being trivially copyable (the difference with <code>__has_trivial_copy</code>) seems to be that the newer intrinsic does take the requirement of a non-trivial destructor into account). </p> </blockquote> <p> A trivially copyable class must have: </p> <ul><li>No non-trivial copy constructors </li><li>No non-trivial copy assignment operators </li><li>No non-trivial move constructors </li><li>No non-trivial move assignment operators </li><li>A trivial destructor </li></ul><p> <code>__has_trivial_copy</code> simply reports whether the class has a trivial copy constructor. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 02 Dec 2015 13:57:59 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:9</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11229#comment:8" title="Comment 8">joseph.thomson@…</a>: </p> <blockquote class="citation"> <p> A trivially copyable class must have: </p> <ul><li>No non-trivial copy constructors </li><li>No non-trivial copy assignment operators </li><li>No non-trivial move constructors </li><li>No non-trivial move assignment operators </li><li>A trivial destructor </li></ul><p> <code>__has_trivial_copy</code> simply reports whether the class has a trivial copy constructor. </p> </blockquote> <p> I get that, and I see that for clang there's a workaround so that boost::has_trivial_copy *also* checks whether it is copy constructible (boost/type_traits/has_trivial_copy.hpp ) </p> <pre class="wiki">template &lt;typename T&gt; struct has_trivial_copy_impl { #ifdef BOOST_HAS_TRIVIAL_COPY # ifdef __clang__ // Why not do this for GCC 4.9 too? BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T) &amp;&amp; boost::is_copy_constructible&lt;T&gt;::value); # else BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T)); # endif #else BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and&lt; ::boost::is_pod&lt;T&gt;::value, ::boost::type_traits::ice_not&lt; ::boost::is_volatile&lt;T&gt;::value &gt;::value &gt;::value)); #endif </pre><blockquote> <p> but this is only the case for Clang, not for GCC 4.9 and up; even though the semantics of the intrinsic for Clang and GCC are the same; so that's the problem I think needs addressing (and was the original intend of the ticket). </p> </blockquote> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Wed, 02 Dec 2015 14:30:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:10</guid> <description> <p> Actually, as far as I can see, the workaround will result in incorrect behaviour. It's been a while since I filed the original ticket, so I can't remember all the details, but I assume that the workaround exists to emulate the old (incorrect) behaviour of GCC on Clang. </p> <p> Implicitly generated, <code>default</code>ed and <code>delete</code>d copy constructors are <em>all</em> trivial. Thus, <code>boost::has_trivial_copy</code> should be true for a <code>std::unique_ptr</code>. This reflects the new, <em>correct</em> behaviour of <code>__has_trivial_copy</code> in GCC 4.9. However, to be trivially copy constructible, a class must: </p> <ul><li>have no non-trivial copy constructors, and </li><li>be copy constructible. </li></ul><p> A <code>std::unique_ptr</code> is not copy constructible, even thought it has a trivial (<code>delete</code>d) copy constructor, so the standard library function <code>std::is_trivially_copy_constructible</code> should be false for a <code>std::unique_ptr</code>. </p> <p> What I'm saying is that, if what you report is accurate, the behaviour of <code>boost::has_trivial_copy</code> is currently wrong for both GCC <em>and</em> Clang. It seemingly behaves like <code>std::is_trivially_copy_constructible</code>. </p> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Wed, 02 Dec 2015 14:32:42 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:11</guid> <description> <p> To avoid confusion: </p> <blockquote class="citation"> <p> behaviour of GCC<del> on Clang</del>. </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 02 Dec 2015 14:56:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:12</guid> <description> <p> Cool, that clears up what boost::has_trivial_copy means, and but then we still have your comment here right: </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11229#comment:3" title="Comment 3">joseph.thomson@…</a>: </p> <blockquote class="citation"> <p> The is_memtransfer_copy_constructible and is_memtransfer_copy_assignable functions, as far as I can tell, perform the same function as is_trivially_copy_constructible and is_trivially_copy_assignable, but they still have incorrect implementations which rely only on boost::has_trivial_copy and boost::has_trivial_assign. Surely you need to change the implementation of these functions to fix the problem? </p> </blockquote> <p> Because now although I'm happy I understand what <code>has_trivial_copy</code> should do I'm still a bit at a loss for which combinations of boost and compiler a <code>boost::vector</code> of <code>unique_ptr</code> will result in double free. </p> <p> As far as I understand: </p> <ul><li>GCC 4.7 &amp; 4.8 are fine (because their intrinsic is broken) </li><li>GCC 4.9 with boost 1.58 is susceptible to the problem </li><li>Clang in fact is fine (but for the wrong reason) </li></ul><ul><li>GCC 4.9 with boost 1.59 (fixed or not?) </li></ul> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Wed, 02 Dec 2015 17:05:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:13</guid> <description> <p> Following the trail: </p> <p> <code>boost/container/detail/copy_move_algo.hpp</code> </p> <pre class="wiki">template &lt;typename I, typename O&gt; struct is_memtransfer_copy_constructible : boost::move_detail::and_ &lt; are_contiguous_and_same&lt;I, O&gt; , container_detail::is_trivially_copy_constructible&lt; typename ::boost::container::iterator_traits&lt;I&gt;::value_type &gt; &gt; {}; </pre><p> <code>boost/container/detail/type_traits.hpp</code> </p> <pre class="wiki">using ::boost::move_detail::is_trivially_copy_constructible; </pre><p> <code>boost/move/detail/type_traits.hpp</code> </p> <pre class="wiki">template&lt;class T&gt; struct is_trivially_copy_constructible { //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with //deleted copy constructors so make sure the type is copy constructible. static const bool value = ::boost::move_detail::is_pod&lt;T&gt;::value || ( ::boost::move_detail::is_copy_constructible&lt;T&gt;::value &amp;&amp; BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) ); }; </pre><pre class="wiki">#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_COPY(T) #else #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod&lt;T&gt;::value #endif </pre><p> <em>MSVC</em> </p> <pre class="wiki"># define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T)|| ::boost::move_detail::is_pod&lt;T&gt;::value) </pre><p> <em>Clang</em> </p> <pre class="wiki"># if __has_feature(has_trivial_copy) # //There are problems with deleted copy constructors detected as trivially copyable. # //http://stackoverflow.com/questions/12754886/has-trivial-copy-behaves-differently-in-clang-and-gcc-whos-right # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) &amp;&amp; ::boost::move_detail::is_copy_constructible&lt;T&gt;::value) # endif </pre><p> GCC </p> <pre class="wiki"># define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) </pre><p> <em>Note that Boost.Container no longer depends on Boost.<a class="missing wiki">TypeTraits</a>, so the code you cited is not actually being used.</em> </p> <p> The original bug existed because Boost.Container only required <code>boost::has_trivial_copy</code> to be true to enable the <code>memcpy</code> optimization, and in GCC 4.9 the behaviour of <code>__has_trivial_copy</code> was fixed, meaning that <code>boost::has_trivial_copy</code> worked correctly in Boost 1.58 with GCC 4.9, meaning that Boost.Containers thought that <code>std::unique_ptr</code> was <code>memcpy</code>-able. </p> <p> As you can see above, Boost.Container fixed the bug by depending on <code>boost::move_detail::is_trivially_copy_constructible</code> instead, which is the correct thing to do (<code>std::unique_ptr</code> should give false for this). As you can see, Boost.Move implements this by explicitly checking whether the class is copy constructible, so this bug should be gone on all compilers in Boost 1.59. </p> <p> But looking at Boost.Move, <code>BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE</code> is incorrectly implemented as <code>BOOST_MOVE_HAS_TRIVIAL_COPY</code>. However, <code>BOOST_MOVE_HAS_TRIVIAL_COPY</code> behaves incorrectly on GCC 4.8 and MSVC, due to <code>__has_trivial_move</code> being broken, which means that <code>BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE</code> actually behaves correctly. This is also the case on Clang, but only because that "fix" has been applied to make it behave like GCC 4.8. Conversely, <code>BOOST_MOVE_HAS_TRIVIAL_COPY</code> behaves correctly on GCC 4.9, while <code>BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE</code> behaves incorrectly. </p> <p> Thus, Boost.Move needs to do the following to fix these problems: </p> <ul><li>Remove the "fix" for Clang </li><li>Implement <code>BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE</code> correctly </li><li>Document that <code>BOOST_MOVE_HAS_TRIVIAL_COPY</code> doesn't work on GCC 4.8 or MSVC </li></ul><p> It is possible that they may be able to use SFINAE on GCC 4.8 to detect the lack of copy constructor, but I have already tried this on MSVC, and the bug exists with the SFINAE (alas, this may be the case with GCC 4.8 as well). </p> <p> <em>p.s. I have no access to GCC or Clang, so I was unable to test by conclusions. Perhaps you could?</em> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 03 Dec 2015 14:57:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:14</guid> <description> <p> So, boost container indeed seems fixed, it behaves correct for Boost 1.59 with any compiler I threw at it (GCC 4.7, 4.9, 5.1 and Clang 3.7); the type traits themselves are indeed broken in the way you describe. </p> <p> So test program is this: </p> <pre class="wiki">#include &lt;memory&gt; #include &lt;boost/type_traits.hpp&gt; static_assert(boost::has_trivial_copy&lt;std::unique_ptr&lt;int&gt;&gt;::value, "unique ptr should have a trivial copy constructor"); </pre><p> This fails for GCC 4.7 and Clang 3.7 (due to the workaround in boost) but succeeds for GCC 4.9 and GCC 5.1. </p> <p> Since <code>has_trivial_copy_constructor</code> is synonymous, you'll find that the assert fails for GCC 4.7 and Clang 3.7 again, but is true for GCC 4.9 and 5.1; indeed showing the converse behaviour. </p> <p> When it comes to boost vector, the following dies badly for Boost 1.58 and GCC 4.9 / 5.1 but is fine for Boost 1.59 with any compiler (or for boost 1.58 with GCC 4.7 / Clang): </p> <pre class="wiki">#include &lt;memory&gt; #include &lt;boost/container/vector.hpp&gt; int main() { auto v = boost::container::vector&lt;std::unique_ptr&lt;int&gt;&gt;{}; for (auto i = 0u; i &lt; 1000*1000; ++i) v.emplace_back(new int(i)); } </pre><p> Thanks for your help, it has been quite useful! </p> </description> <category>Ticket</category> </item> <item> <author>joseph.thomson@…</author> <pubDate>Thu, 03 Dec 2015 19:29:15 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11229#comment:15 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11229#comment:15</guid> <description> <p> No problem. </p> <p> I'm not sure about <code>boost::has_trivial_copy</code> though, because that is part of Boost.<a class="missing wiki">TypeTraits</a>, not Boost.Move. I was describing how <code>BOOST_MOVE_HAS_TRIVIAL_COPY</code> and <code>BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE</code> are variously broken on different compilers. These are internal macros, so perhaps it isn't too big of a deal. </p> <p> A separate bug report needs to be filed for <code>boost::has_trivial_copy</code>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Thu, 30 Jun 2016 14:24:27 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11229#comment:16 https://svn.boost.org/trac10/ticket/11229#comment:16 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Boost.Move's intrinsic macros are internal so there is no requirement to implement the standard wording. In any case the special Clang case will be removed and internally the library will assume that BOOST_MOVE_HAS_TRIVIAL_COPY does not guarantee the copy constructor is callable. Change committed: </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/e7d24400cb986efaefa0acbff5de6e74eae876d9"><span class="icon">​</span>https://github.com/boostorg/move/commit/e7d24400cb986efaefa0acbff5de6e74eae876d9</a> </p> Ticket