diff options
author | Jordan Rose <jordan_rose@apple.com> | 2016-10-10 20:57:33 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2016-10-10 20:57:33 +0000 |
commit | d77cee3f54bee1d32bd269827b27d889c8962db1 (patch) | |
tree | 686aa21d241da1fb1f913e23679578856e4e7d2b /llvm/unittests/ADT/ArrayRefTest.cpp | |
parent | fcd2421667582cdceff8bf30d65b262998d3cd59 (diff) | |
download | bcm5719-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.cpp | 23 |
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}; |