diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-12 00:39:32 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-12 00:39:32 +0000 |
| commit | dca60b495822a869c08b9973e4c485a83e8b6c0e (patch) | |
| tree | 2fdde29c41a18a0db2b21eee23a45ddf8a6fc75c /clang/test | |
| parent | e5cc668eb823dc8eb0e6013289846d25b6e82293 (diff) | |
| download | bcm5719-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.cpp | 7 | ||||
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp | 29 | ||||
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp | 8 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1z-decomposition.cpp | 22 |
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 |

