From dc6b70d7363dfd4e0ef7f5b3949605b92760ec0d Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 7 Oct 2016 21:07:22 -0700 Subject: [PATCH] Disallow ArrayRef assignment from temporaries. Without this, the following statements will create ArrayRefs that refer to temporary storage that goes out of scope by the end of the line: someArrayRef = getSingleElement(); someArrayRef = {elem1, elem2}; Note that the constructor still has this problem: ArrayRef someArrayRef = getSingleElement(); ArrayRef someArrayRef = {elem1, elem2}; but that's a little harder to get rid of because we want to be able to use this in calls: takesArrayRef(getSingleElement()); takesArrayRef({elem1, elem2}); Part of rdar://problem/16375365 --- include/llvm/ADT/ArrayRef.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index bfe851485f3..41a54c390bc 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -203,6 +203,22 @@ namespace llvm { 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 std::enable_if::value, ArrayRef>::type & + operator=(U &&Temporary) = delete; + + /// Disallow accidental assignment from a temporary. + /// + /// The declaration here is extra complicated so that "arrayRef = {}" + /// continues to select the move assignment operator. + template + typename std::enable_if::value, ArrayRef>::type & + operator=(std::initializer_list) = delete; + /// @} /// @name Expensive Operations /// @{