<div dir="ltr">@Hans While working on the std::tuple bug I found this bug in std::pair. Since we are already doing another RC I would like to merge this fix.<div><br></div><div>@Marshall Sound OK to you?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Aug 28, 2016 at 7:09 PM, Eric Fiselier via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ericwf<br>
Date: Sun Aug 28 20:09:47 2016<br>
New Revision: 279953<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=279953&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=279953&view=rev</a><br>
Log:<br>
Fix pair::operator=(TupleLike&&).<br>
<br>
This assignment operator was previously broken since the SFINAE always resulted<br>
in substitution failure. This caused assignments to turn into<br>
copy construction + assignment.<br>
<br>
Added:<br>
    libcxx/trunk/test/std/<wbr>utilities/utility/pairs/pairs.<wbr>pair/assign_tuple.pass.cpp<br>
Modified:<br>
    libcxx/trunk/include/utility<br>
<br>
Modified: libcxx/trunk/include/utility<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=279953&r1=279952&r2=279953&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/libcxx/trunk/include/<wbr>utility?rev=279953&r1=279952&<wbr>r2=279953&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- libcxx/trunk/include/utility (original)<br>
+++ libcxx/trunk/include/utility Sun Aug 28 20:09:47 2016<br>
@@ -515,7 +515,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair<br>
     }<br>
<br>
     template <class _Tuple, _EnableB<<br>
-            _CheckTLC<_Tuple>::template __enable_assign()<br>
+            _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()<br>
      > = false><br>
     _LIBCPP_INLINE_VISIBILITY<br>
     pair& operator=(_Tuple&& __p) {<br>
<br>
Added: libcxx/trunk/test/std/<wbr>utilities/utility/pairs/pairs.<wbr>pair/assign_tuple.pass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp?rev=279953&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/libcxx/trunk/test/std/<wbr>utilities/utility/pairs/pairs.<wbr>pair/assign_tuple.pass.cpp?<wbr>rev=279953&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- libcxx/trunk/test/std/<wbr>utilities/utility/pairs/pairs.<wbr>pair/assign_tuple.pass.cpp (added)<br>
+++ libcxx/trunk/test/std/<wbr>utilities/utility/pairs/pairs.<wbr>pair/assign_tuple.pass.cpp Sun Aug 28 20:09:47 2016<br>
@@ -0,0 +1,135 @@<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <utility><br>
+<br>
+// template <class T1, class T2> struct pair<br>
+<br>
+// template<class U, class V> pair& operator=(tuple<U, V>&& p);<br>
+<br>
+#include <utility><br>
+#include <tuple><br>
+#include <array><br>
+#include <memory><br>
+#include <cassert><br>
+<br>
+struct CountingType {<br>
+  static int constructed;<br>
+  static int copy_constructed;<br>
+  static int move_constructed;<br>
+  static int assigned;<br>
+  static int copy_assigned;<br>
+  static int move_assigned;<br>
+  static void reset() {<br>
+      constructed = copy_constructed = move_constructed = 0;<br>
+      assigned = copy_assigned = move_assigned = 0;<br>
+  }<br>
+  CountingType() : value(0) { ++constructed; }<br>
+  CountingType(int v) : value(v) { ++constructed; }<br>
+  CountingType(CountingType const& o) : value(o.value) { ++constructed; ++copy_constructed; }<br>
+  CountingType(CountingType&& o) : value(o.value) { ++constructed; ++move_constructed; o.value = -1;}<br>
+<br>
+  CountingType& operator=(CountingType const& o) {<br>
+      ++assigned;<br>
+      ++copy_assigned;<br>
+      value = o.value;<br>
+      return *this;<br>
+  }<br>
+  CountingType& operator=(CountingType&& o) {<br>
+      ++assigned;<br>
+      ++move_assigned;<br>
+      value = o.value;<br>
+      o.value = -1;<br>
+      return *this;<br>
+  }<br>
+  int value;<br>
+};<br>
+int CountingType::constructed;<br>
+int CountingType::copy_<wbr>constructed;<br>
+int CountingType::move_<wbr>constructed;<br>
+int CountingType::assigned;<br>
+int CountingType::copy_assigned;<br>
+int CountingType::move_assigned;<br>
+<br>
+int main()<br>
+{<br>
+    using C = CountingType;<br>
+    {<br>
+       using P = std::pair<int, C>;<br>
+       using T = std::tuple<int, C>;<br>
+       T t(42, C{42});<br>
+       P p(101, C{101});<br>
+       C::reset();<br>
+       p = t;<br>
+       assert(C::constructed == 0);<br>
+       assert(C::assigned == 1);<br>
+       assert(C::copy_assigned == 1);<br>
+       assert(C::move_assigned == 0);<br>
+       assert(p.first == 42);<br>
+       assert(p.second.value == 42);<br>
+    }<br>
+    {<br>
+       using P = std::pair<int, C>;<br>
+       using T = std::tuple<int, C>;<br>
+       T t(42, -42);<br>
+       P p(101, 101);<br>
+       C::reset();<br>
+       p = std::move(t);<br>
+       assert(C::constructed == 0);<br>
+       assert(C::assigned == 1);<br>
+       assert(C::copy_assigned == 0);<br>
+       assert(C::move_assigned == 1);<br>
+       assert(p.first == 42);<br>
+       assert(p.second.value == -42);<br>
+    }<br>
+    {<br>
+       using P = std::pair<C, C>;<br>
+       using T = std::array<C, 2>;<br>
+       T t = {42, -42};<br>
+       P p{101, 101};<br>
+       C::reset();<br>
+       p = t;<br>
+       assert(C::constructed == 0);<br>
+       assert(C::assigned == 2);<br>
+       assert(C::copy_assigned == 2);<br>
+       assert(C::move_assigned == 0);<br>
+       assert(p.first.value == 42);<br>
+       assert(p.second.value == -42);<br>
+    }<br>
+    {<br>
+       using P = std::pair<C, C>;<br>
+       using T = std::array<C, 2>;<br>
+       T t = {42, -42};<br>
+       P p{101, 101};<br>
+       C::reset();<br>
+       p = t;<br>
+       assert(C::constructed == 0);<br>
+       assert(C::assigned == 2);<br>
+       assert(C::copy_assigned == 2);<br>
+       assert(C::move_assigned == 0);<br>
+       assert(p.first.value == 42);<br>
+       assert(p.second.value == -42);<br>
+    }<br>
+    {<br>
+       using P = std::pair<C, C>;<br>
+       using T = std::array<C, 2>;<br>
+       T t = {42, -42};<br>
+       P p{101, 101};<br>
+       C::reset();<br>
+       p = std::move(t);<br>
+       assert(C::constructed == 0);<br>
+       assert(C::assigned == 2);<br>
+       assert(C::copy_assigned == 0);<br>
+       assert(C::move_assigned == 2);<br>
+       assert(p.first.value == 42);<br>
+       assert(p.second.value == -42);<br>
+    }<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>