diff options
author | Jason Merrill <jason@redhat.com> | 2016-03-01 21:32:38 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-03-01 21:32:38 -0500 |
commit | 7f0e23e931064d8e8758e01d95bfb89b8fa32e6e (patch) | |
tree | 0cc8022bd94df7f07d7abb5a2bc52688bc6557ba /gcc | |
parent | 4be9717cf879d45534da0044401885e508c5d562 (diff) | |
download | gcc-7f0e23e931064d8e8758e01d95bfb89b8fa32e6e.zip gcc-7f0e23e931064d8e8758e01d95bfb89b8fa32e6e.tar.gz gcc-7f0e23e931064d8e8758e01d95bfb89b8fa32e6e.tar.bz2 |
re PR c++/69995 ([C++14] Invalid result when evaluating constexpr function)
PR c++/69995
* constexpr.c (cxx_eval_call_expression): Unshare arg.
(cxx_eval_constant_expression) [DECL_EXPR]: Unshare init.
[TARGET_EXPR]: Unshare init.
From-SVN: r233877
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-copy2.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-copy3.C | 26 |
4 files changed, 62 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 04e1426..3a24cc9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-03-01 Jason Merrill <jason@redhat.com> + + PR c++/69995 + * constexpr.c (cxx_eval_call_expression): Unshare arg. + (cxx_eval_constant_expression) [DECL_EXPR]: Unshare init. + [TARGET_EXPR]: Unshare init. + 2016-03-01 Patrick Palka <ppalka@gcc.gnu.org> PR c++/68948 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 5e35940..a21997a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1365,6 +1365,8 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, tree oparm = TREE_PURPOSE (bound); tree arg = TREE_VALUE (bound); gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm)); + /* Don't share a CONSTRUCTOR that might be changed. */ + arg = unshare_expr (arg); ctx->values->put (remapped, arg); bound = TREE_CHAIN (bound); remapped = DECL_CHAIN (remapped); @@ -3366,6 +3368,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, init = cxx_eval_constant_expression (ctx, init, false, non_constant_p, overflow_p); + /* Don't share a CONSTRUCTOR that might be changed. */ + init = unshare_expr (init); ctx->values->put (r, init); } else if (ctx == &new_ctx) @@ -3410,6 +3414,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (lval) { tree slot = TARGET_EXPR_SLOT (t); + r = unshare_expr (r); ctx->values->put (slot, r); return slot; } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-copy2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy2.C new file mode 100644 index 0000000..6707975 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy2.C @@ -0,0 +1,24 @@ +// PR c++/69995 +// { dg-do compile { target c++14 } } + +struct A +{ + int i; +}; + +constexpr int f(A a) +{ + ++a.i; + return a.i; +} + +constexpr bool g() +{ + A a = { 42 }; + if (f(a) != 43) return false; + if (a.i != 42) return false; + return true; +} + +#define SA(X) static_assert((X),#X) +SA(g()); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-copy3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy3.C new file mode 100644 index 0000000..cce4b54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy3.C @@ -0,0 +1,26 @@ +// PR c++/69995 +// { dg-do compile { target c++14 } } + +struct A +{ + int i; +}; + +constexpr int f(A a) +{ + ++a.i; + return a.i; +} + +constexpr bool g() +{ + A a = { 42 }; + A b = a; + ++b.i; + if (b.i != 43) return false; + if (a.i != 42) return false; + return true; +} + +#define SA(X) static_assert((X),#X) +SA(g()); |