Commit 255a48d6 by Jason Merrill Committed by Jason Merrill

* constexpr.c (cxx_eval_indirect_ref): Try folding first.

From-SVN: r223902
parent 6ad6af49
2015-05-31 Jason Merrill <jason@redhat.com> 2015-05-31 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_indirect_ref): Try folding first.
PR c++/66320 PR c++/66320
* constexpr.c (cxx_eval_constant_expression): Treat a placeholder * constexpr.c (cxx_eval_constant_expression): Treat a placeholder
with the wrong type as non-constant. with the wrong type as non-constant.
......
...@@ -2427,30 +2427,31 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, ...@@ -2427,30 +2427,31 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
bool *non_constant_p, bool *overflow_p) bool *non_constant_p, bool *overflow_p)
{ {
tree orig_op0 = TREE_OPERAND (t, 0); tree orig_op0 = TREE_OPERAND (t, 0);
bool empty_base = false;
/* First try to simplify it directly. */
tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0,
&empty_base);
if (!r)
{
/* If that didn't work, evaluate the operand first. */
tree op0 = cxx_eval_constant_expression (ctx, orig_op0, tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
/*lval*/false, non_constant_p, /*lval*/false, non_constant_p,
overflow_p); overflow_p);
bool empty_base = false;
tree r;
/* Don't VERIFY_CONSTANT here. */ /* Don't VERIFY_CONSTANT here. */
if (*non_constant_p) if (*non_constant_p)
return t; return t;
r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0, r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
&empty_base); &empty_base);
if (r == NULL_TREE)
if (r)
r = cxx_eval_constant_expression (ctx, r,
lval, non_constant_p, overflow_p);
else
{ {
/* We couldn't fold to a constant value. Make sure it's not
something we should have been able to fold. */
tree sub = op0; tree sub = op0;
STRIP_NOPS (sub); STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR) if (TREE_CODE (sub) == ADDR_EXPR)
{ {
/* We couldn't fold to a constant value. Make sure it's not
something we should have been able to fold. */
gcc_assert (!same_type_ignoring_top_level_qualifiers_p gcc_assert (!same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */ /* DR 1188 says we don't have to deal with this. */
...@@ -2461,8 +2462,20 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, ...@@ -2461,8 +2462,20 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
*non_constant_p = true; *non_constant_p = true;
return t; return t;
} }
if (lval && op0 != orig_op0)
return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
if (!lval)
VERIFY_CONSTANT (t);
return t;
}
} }
r = cxx_eval_constant_expression (ctx, r,
lval, non_constant_p, overflow_p);
if (*non_constant_p)
return t;
/* If we're pulling out the value of an empty base, make sure /* If we're pulling out the value of an empty base, make sure
that the whole object is constant and then return an empty that the whole object is constant and then return an empty
CONSTRUCTOR. */ CONSTRUCTOR. */
...@@ -2473,14 +2486,6 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, ...@@ -2473,14 +2486,6 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
TREE_CONSTANT (r) = true; TREE_CONSTANT (r) = true;
} }
if (r == NULL_TREE)
{
if (lval && op0 != orig_op0)
return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
if (!lval)
VERIFY_CONSTANT (t);
return t;
}
return r; return r;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment