[PATCH] D25446: Disallow ArrayRef assignment from temporaries
Duncan P. N. Exon Smith via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 10 13:24:13 PDT 2016
> On 2016-Oct-10, at 12:35, Jordan Rose <jordan_rose at apple.com> wrote:
>
> jordan_rose created this revision.
> jordan_rose added reviewers: chandlerc, dexonsmith.
> jordan_rose added a subscriber: llvm-commits.
> jordan_rose set the repository for this revision to rL LLVM.
>
> Without this, the following statements will create ArrayRefs that refer to temporary storage that goes out of scope by the end of the line:
>
> c++
> someArrayRef = getSingleElement();
> someArrayRef = {elem1, elem2};
>
> Note that the constructor still has this problem:
>
> c++
> ArrayRef<Element> someArrayRef = getSingleElement();
> ArrayRef<Element> someArrayRef = {elem1, elem2};
Long-term, I think these constructors should be explicit.
> but that's a little harder to get rid of because we want to be able to use this in calls:
>
> c++
> takesArrayRef(getSingleElement());
> takesArrayRef({elem1, elem2});
These would have to change to:
takesArrayRef(makeArrayRef(getSingleElement()));
takesArrayRef(makeArrayRef({elem1, elem2}));
but I think that would be a fine tradeoff.
>
> Part of rdar://problem/16375365.
>
>
> Repository:
> rL LLVM
>
> https://reviews.llvm.org/D25446
>
> Files:
> include/llvm/ADT/ArrayRef.h
>
>
> Index: include/llvm/ADT/ArrayRef.h
> ===================================================================
> --- include/llvm/ADT/ArrayRef.h
> +++ include/llvm/ADT/ArrayRef.h
> @@ -219,6 +219,22 @@
> return Data[Index];
> }
>
> + /// Disallow accidental assignment from a temporary.
> + ///
> + /// The declaration here is extra complicated so that "arrayRef = {}"
> + /// continues to select the move assignment operator.
> + template <typename U>
> + typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
> + operator=(U &&Temporary) = delete;
I'm not sure the parameter name, "Temporary", is worth spelling out.
LGTM (with or without the name) if you add std::is_assignable-based static_asserts to unittests/ADT/ArrayRefTest.cpp.
> +
> + /// Disallow accidental assignment from a temporary.
> + ///
> + /// The declaration here is extra complicated so that "arrayRef = {}"
> + /// continues to select the move assignment operator.
> + template <typename U>
> + typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
> + operator=(std::initializer_list<U>) = delete;
> +
> /// @}
> /// @name Expensive Operations
> /// @{
>
>
> <D25446.74161.patch>
More information about the llvm-commits
mailing list