summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ADT/ArrayRefTest.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2016-10-10 20:57:33 +0000
committerJordan Rose <jordan_rose@apple.com>2016-10-10 20:57:33 +0000
commitd77cee3f54bee1d32bd269827b27d889c8962db1 (patch)
tree686aa21d241da1fb1f913e23679578856e4e7d2b /llvm/unittests/ADT/ArrayRefTest.cpp
parentfcd2421667582cdceff8bf30d65b262998d3cd59 (diff)
downloadbcm5719-llvm-d77cee3f54bee1d32bd269827b27d889c8962db1.tar.gz
bcm5719-llvm-d77cee3f54bee1d32bd269827b27d889c8962db1.zip
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<Element> someArrayRef = getSingleElement(); ArrayRef<Element> 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. Reviewed by Duncan Exon Smith. llvm-svn: 283798
Diffstat (limited to 'llvm/unittests/ADT/ArrayRefTest.cpp')
-rw-r--r--llvm/unittests/ADT/ArrayRefTest.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp
index 43e5005e62d..f046da8a833 100644
--- a/llvm/unittests/ADT/ArrayRefTest.cpp
+++ b/llvm/unittests/ADT/ArrayRefTest.cpp
@@ -31,6 +31,21 @@ static_assert(
!std::is_convertible<ArrayRef<volatile int *>, ArrayRef<int *>>::value,
"Removing volatile");
+// Check that we can't accidentally assign a temporary location to an ArrayRef.
+// (Unfortunately we can't make use of the same thing with constructors.)
+static_assert(
+ !std::is_assignable<ArrayRef<int *>, int *>::value,
+ "Assigning from single prvalue element");
+static_assert(
+ !std::is_assignable<ArrayRef<int *>, int * &&>::value,
+ "Assigning from single xvalue element");
+static_assert(
+ std::is_assignable<ArrayRef<int *>, int * &>::value,
+ "Assigning from single lvalue element");
+static_assert(
+ !std::is_assignable<ArrayRef<int *>, std::initializer_list<int *>>::value,
+ "Assigning from an initializer list");
+
namespace {
TEST(ArrayRefTest, AllocatorCopy) {
@@ -161,6 +176,14 @@ TEST(ArrayRefTest, InitializerList) {
ArgTest12({1, 2});
}
+TEST(ArrayRefTest, EmptyInitializerList) {
+ ArrayRef<int> A = {};
+ EXPECT_TRUE(A.empty());
+
+ A = {};
+ EXPECT_TRUE(A.empty());
+}
+
// Test that makeArrayRef works on ArrayRef (no-op)
TEST(ArrayRefTest, makeArrayRef) {
static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};
OpenPOWER on IntegriCloud