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
This commit is contained in:
Jason Merrill 2016-03-01 21:32:38 -05:00 committed by Jason Merrill
parent 4be9717cf8
commit 7f0e23e931
4 changed files with 62 additions and 0 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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());

View File

@ -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());