From: jason Date: Mon, 29 Feb 2016 14:25:57 +0000 (+0000) Subject: PR c++/69995 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b9f713d45d4a3b6c8577a7b088dfc3c31e6a505;p=thirdparty%2Fgcc.git PR c++/69995 * constexpr.c (cxx_eval_store_expression): Unshare init. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233810 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ec991201009f..49ca2f273fda 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 8d9168c39507..5e359404c8d6 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 000000000000..8cea41a1cb71 --- /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); +}