summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-08-12 00:39:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-08-12 00:39:32 +0000
commitdca60b495822a869c08b9973e4c485a83e8b6c0e (patch)
tree2fdde29c41a18a0db2b21eee23a45ddf8a6fc75c /clang/test
parente5cc668eb823dc8eb0e6013289846d25b6e82293 (diff)
downloadbcm5719-llvm-dca60b495822a869c08b9973e4c485a83e8b6c0e.tar.gz
bcm5719-llvm-dca60b495822a869c08b9973e4c485a83e8b6c0e.zip
P0217R3: Constant expression evaluation for decomposition declarations.
llvm-svn: 278447
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp7
-rw-r--r--clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp29
-rw-r--r--clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp8
-rw-r--r--clang/test/SemaCXX/cxx1z-decomposition.cpp22
4 files changed, 60 insertions, 6 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp
index cd0518bfc59..639aff64dfc 100644
--- a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -std=c++1z -verify %s
int array() {
- int arr[3] = {};
+ static int arr[3] = {};
// FIXME: We are supposed to create an array object here and perform elementwise initialization.
auto [a, b, c] = arr; // expected-error {{cannot decompose non-class, non-array}}
@@ -11,8 +11,9 @@ int array() {
auto &[r0, r1, r2] = arr;
const auto &[cr0, cr1, cr2] = arr;
- //static_assert(&arr[0] == &r0);
- //static_assert(&arr[0] == &cr0);
+ static_assert(&arr[0] == &r0);
+ static_assert(&arr[0] == &cr0);
+
using T = int;
using T = decltype(r0);
using U = const int;
diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
index 1acf391c9f3..e4a7a6c4f98 100644
--- a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
@@ -201,3 +201,32 @@ void test_value_category() {
{ auto [a] = wrap<const int, void, float&>(); } // ok, const int &a can bind to float
{ auto [a] = wrap<int, void, float>(); } // ok, int &&a can bind to float
}
+
+namespace constant {
+ struct Q {};
+ template<int N> constexpr int get(Q &&) { return N * N; }
+}
+template<> struct std::tuple_size<constant::Q> { static const int value = 3; };
+template<int N> struct std::tuple_element<N, constant::Q> { typedef int type; };
+namespace constant {
+ Q q;
+ // This creates and lifetime-extends a temporary to hold the result of each get() call.
+ auto [a, b, c] = q; // expected-note {{temporary}}
+ static_assert(a == 0); // expected-error {{constant expression}} expected-note {{temporary}}
+
+ constexpr bool f() {
+ auto [a, b, c] = q;
+ return a == 0 && b == 1 && c == 4;
+ }
+ static_assert(f());
+
+ constexpr int g() {
+ int *p = nullptr;
+ {
+ auto [a, b, c] = q;
+ p = &c;
+ }
+ return *p; // expected-note {{read of object outside its lifetime}}
+ }
+ static_assert(g() == 4); // expected-error {{constant}} expected-note {{in call to 'g()'}}
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp
index 3a72ae0e33a..ea225cbf9ab 100644
--- a/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp
@@ -163,6 +163,14 @@ namespace Bitfield {
}
}
+namespace Constexpr {
+ struct Q { int a, b; constexpr Q() : a(1), b(2) {} };
+ constexpr Q q;
+ auto &[qa, qb] = q;
+ static_assert(&qa == &q.a && &qb == &q.b);
+ static_assert(qa == 1 && qb == 2);
+}
+
namespace std_example {
struct S { int x1 : 2; volatile double y1; };
S f();
diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index 6541476a67b..3b1e49cb078 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -6,9 +6,13 @@ void use_from_own_init() {
// As a Clang extension, _Complex can be decomposed.
float decompose_complex(_Complex float cf) {
+ static _Complex float scf;
+ auto &[sre, sim] = scf;
+ // ok, this is references initialized by constant expressions all the way down
+ static_assert(&sre == &__real scf);
+ static_assert(&sim == &__imag scf);
+
auto [re, im] = cf;
- //static_assert(&re == &__real cf);
- //static_assert(&im == &__imag cf);
return re*re + im*im;
}
@@ -20,8 +24,20 @@ float decompose_vector(vf3 v) {
return x + y + z;
}
+struct S { int a, b; };
+constexpr int f(S s) {
+ auto &[a, b] = s;
+ return a * 10 + b;
+}
+static_assert(f({1, 2}) == 12);
+
+constexpr bool g(S &&s) {
+ auto &[a, b] = s;
+ return &a == &s.a && &b == &s.b && &a != &b;
+}
+static_assert(g({1, 2}));
+
// FIXME: by-value array copies
// FIXME: template instantiation
// FIXME: ast file support
// FIXME: code generation
-// FIXME: constant expression evaluation
OpenPOWER on IntegriCloud