diff options
author | Jason Merrill <jason@redhat.com> | 2016-02-29 09:25:57 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-02-29 09:25:57 -0500 |
commit | 7574c916aeb5e7f5dfdf0302138e02f1a83cfaba (patch) | |
tree | 6ad3af10a204a96d688eaf14bc5c07cdef306bfb /gcc | |
parent | cbd400b43e4068a886b7297e4da8599732ef6813 (diff) | |
download | gcc-7574c916aeb5e7f5dfdf0302138e02f1a83cfaba.zip gcc-7574c916aeb5e7f5dfdf0302138e02f1a83cfaba.tar.gz gcc-7574c916aeb5e7f5dfdf0302138e02f1a83cfaba.tar.bz2 |
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
Diffstat (limited to 'gcc')
-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); +} |