<div dir="ltr">Hi Jordan,<div><br></div><div>I have to revert this as it is causing build failures on MSVC 2015 with the following messages:</div><div><br></div><div><div>    ArrayRefTest.cpp(38): error C2338: Assigning from single prvalue element</div><div>    ArrayRefTest.cpp(41): error C2338: Assigning from single xvalue element</div><div>    ArrayRefTest.cpp(47): error C2338: Assigning from an initializer list</div></div><div><br></div><div>Unfortunately I don't have time to dig further at the moment and we're having bot failures pile up right now so I'm trying to get back to green.</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 10, 2016 at 2:06 PM Jordan Rose via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jrose<br class="gmail_msg">
Date: Mon Oct 10 15:57:33 2016<br class="gmail_msg">
New Revision: 283798<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=283798&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=283798&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
Disallow ArrayRef assignment from temporaries.<br class="gmail_msg">
<br class="gmail_msg">
Without this, the following statements will create ArrayRefs that<br class="gmail_msg">
refer to temporary storage that goes out of scope by the end of the<br class="gmail_msg">
line:<br class="gmail_msg">
<br class="gmail_msg">
  someArrayRef = getSingleElement();<br class="gmail_msg">
  someArrayRef = {elem1, elem2};<br class="gmail_msg">
<br class="gmail_msg">
Note that the constructor still has this problem:<br class="gmail_msg">
<br class="gmail_msg">
  ArrayRef<Element> someArrayRef = getSingleElement();<br class="gmail_msg">
  ArrayRef<Element> someArrayRef = {elem1, elem2};<br class="gmail_msg">
<br class="gmail_msg">
but that's a little harder to get rid of because we want to be able to<br class="gmail_msg">
use this in calls:<br class="gmail_msg">
<br class="gmail_msg">
  takesArrayRef(getSingleElement());<br class="gmail_msg">
  takesArrayRef({elem1, elem2});<br class="gmail_msg">
<br class="gmail_msg">
Part of rdar://problem/16375365. Reviewed by Duncan Exon Smith.<br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    llvm/trunk/include/llvm/ADT/ArrayRef.h<br class="gmail_msg">
    llvm/trunk/unittests/ADT/ArrayRefTest.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/ADT/ArrayRef.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=283798&r1=283797&r2=283798&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=283798&r1=283797&r2=283798&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/ADT/ArrayRef.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/ADT/ArrayRef.h Mon Oct 10 15:57:33 2016<br class="gmail_msg">
@@ -219,6 +219,22 @@ namespace llvm {<br class="gmail_msg">
       return Data[Index];<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// Disallow accidental assignment from a temporary.<br class="gmail_msg">
+    ///<br class="gmail_msg">
+    /// The declaration here is extra complicated so that "arrayRef = {}"<br class="gmail_msg">
+    /// continues to select the move assignment operator.<br class="gmail_msg">
+    template <typename U><br class="gmail_msg">
+    typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &<br class="gmail_msg">
+    operator=(U &&Temporary) = delete;<br class="gmail_msg">
+<br class="gmail_msg">
+    /// Disallow accidental assignment from a temporary.<br class="gmail_msg">
+    ///<br class="gmail_msg">
+    /// The declaration here is extra complicated so that "arrayRef = {}"<br class="gmail_msg">
+    /// continues to select the move assignment operator.<br class="gmail_msg">
+    template <typename U><br class="gmail_msg">
+    typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &<br class="gmail_msg">
+    operator=(std::initializer_list<U>) = delete;<br class="gmail_msg">
+<br class="gmail_msg">
     /// @}<br class="gmail_msg">
     /// @name Expensive Operations<br class="gmail_msg">
     /// @{<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/unittests/ADT/ArrayRefTest.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ArrayRefTest.cpp?rev=283798&r1=283797&r2=283798&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ArrayRefTest.cpp?rev=283798&r1=283797&r2=283798&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/unittests/ADT/ArrayRefTest.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/unittests/ADT/ArrayRefTest.cpp Mon Oct 10 15:57:33 2016<br class="gmail_msg">
@@ -31,6 +31,21 @@ static_assert(<br class="gmail_msg">
     !std::is_convertible<ArrayRef<volatile int *>, ArrayRef<int *>>::value,<br class="gmail_msg">
     "Removing volatile");<br class="gmail_msg">
<br class="gmail_msg">
+// Check that we can't accidentally assign a temporary location to an ArrayRef.<br class="gmail_msg">
+// (Unfortunately we can't make use of the same thing with constructors.)<br class="gmail_msg">
+static_assert(<br class="gmail_msg">
+    !std::is_assignable<ArrayRef<int *>, int *>::value,<br class="gmail_msg">
+    "Assigning from single prvalue element");<br class="gmail_msg">
+static_assert(<br class="gmail_msg">
+    !std::is_assignable<ArrayRef<int *>, int * &&>::value,<br class="gmail_msg">
+    "Assigning from single xvalue element");<br class="gmail_msg">
+static_assert(<br class="gmail_msg">
+    std::is_assignable<ArrayRef<int *>, int * &>::value,<br class="gmail_msg">
+    "Assigning from single lvalue element");<br class="gmail_msg">
+static_assert(<br class="gmail_msg">
+    !std::is_assignable<ArrayRef<int *>, std::initializer_list<int *>>::value,<br class="gmail_msg">
+    "Assigning from an initializer list");<br class="gmail_msg">
+<br class="gmail_msg">
 namespace {<br class="gmail_msg">
<br class="gmail_msg">
 TEST(ArrayRefTest, AllocatorCopy) {<br class="gmail_msg">
@@ -161,6 +176,14 @@ TEST(ArrayRefTest, InitializerList) {<br class="gmail_msg">
   ArgTest12({1, 2});<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+TEST(ArrayRefTest, EmptyInitializerList) {<br class="gmail_msg">
+  ArrayRef<int> A = {};<br class="gmail_msg">
+  EXPECT_TRUE(A.empty());<br class="gmail_msg">
+<br class="gmail_msg">
+  A = {};<br class="gmail_msg">
+  EXPECT_TRUE(A.empty());<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 // Test that makeArrayRef works on ArrayRef (no-op)<br class="gmail_msg">
 TEST(ArrayRefTest, makeArrayRef) {<br class="gmail_msg">
   static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
llvm-commits mailing list<br class="gmail_msg">
<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg">
</blockquote></div>