From 7574c916aeb5e7f5dfdf0302138e02f1a83cfaba Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 29 Feb 2016 09:25:57 -0500 Subject: [PATCH] re PR c++/69995 ([C++14] Invalid result when evaluating constexpr function) PR c++/69995 * constexpr.c (cxx_eval_store_expression): Unshare init. From-SVN: r233810 --- gcc/cp/ChangeLog | 5 +++ gcc/cp/constexpr.c | 2 + gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C | 43 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ec991201009..49ca2f273fd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-02-28 Jason Merrill + + PR c++/69995 + * constexpr.c (cxx_eval_store_expression): Unshare init. + 2016-02-26 Jason Merrill PR c++/69958 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 8d9168c3950..5e359404c8d 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 00000000000..8cea41a1cb7 --- /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 +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 +CONSTEXPR void my_swap(T& a, T& b) { + T tmp = a; + a = b; + b = tmp; +} + +CONSTEXPR auto rotate2() { + array, 2> result{}; + array 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); +} -- 2.30.2