diff options
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C | 43 |
3 files changed, 50 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ec99120..49ca2f2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-02-28 Jason Merrill <jason@redhat.com> + + PR c++/69995 + * constexpr.c (cxx_eval_store_expression): Unshare init. + 2016-02-26 Jason Merrill <jason@redhat.com> PR c++/69958 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 8d9168c..5e35940 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2925,6 +2925,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, init = cxx_eval_constant_expression (&new_ctx, init, false, non_constant_p, overflow_p); + /* Don't share a CONSTRUCTOR that might be changed later. */ + init = unshare_expr (init); if (target == object) { /* The hash table might have moved since the get earlier. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C new file mode 100644 index 0000000..8cea41a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C @@ -0,0 +1,43 @@ +// PR c++/69995 +// { dg-do compile { target c++14 } } + +#define assert(X) static_assert((X),#X) + +#define CONSTEXPR constexpr + +template <typename T, unsigned long Size> +struct array { + T elems_[Size]; + + constexpr T const& operator[](unsigned long n) const + { return elems_[n]; } + + constexpr T& operator[](unsigned long n) + { return elems_[n]; } +}; + +template <typename T> +CONSTEXPR void my_swap(T& a, T& b) { + T tmp = a; + a = b; + b = tmp; +} + +CONSTEXPR auto rotate2() { + array<array<int, 2>, 2> result{}; + array<int, 2> a{{0, 1}}; + + result[0] = a; + my_swap(a[0], a[1]); + result[1] = a; + + return result; +} + +int main() { + CONSTEXPR auto indices = rotate2(); + assert(indices[0][0] == 0); + assert(indices[0][1] == 1); + assert(indices[1][0] == 1); + assert(indices[1][1] == 0); +} |