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

From-SVN: r223902
This commit is contained in:
Jason Merrill 2015-05-31 16:36:26 -04:00 committed by Jason Merrill
parent 6ad6af49da
commit 255a48d641
2 changed files with 41 additions and 34 deletions

View File

@ -1,5 +1,7 @@
2015-05-31 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_indirect_ref): Try folding first.
PR c++/66320
* constexpr.c (cxx_eval_constant_expression): Treat a placeholder
with the wrong type as non-constant.

View File

@ -2427,42 +2427,55 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
bool *non_constant_p, bool *overflow_p)
{
tree orig_op0 = TREE_OPERAND (t, 0);
tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
/*lval*/false, non_constant_p,
overflow_p);
bool empty_base = false;
tree r;
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
&empty_base);
if (r)
r = cxx_eval_constant_expression (ctx, r,
lval, non_constant_p, overflow_p);
else
/* First try to simplify it directly. */
tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0,
&empty_base);
if (!r)
{
tree sub = op0;
STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR)
/* If that didn't work, evaluate the operand first. */
tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
/*lval*/false, non_constant_p,
overflow_p);
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
&empty_base);
if (r == NULL_TREE)
{
/* 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
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */
if (!ctx->quiet)
error ("accessing value of %qE through a %qT glvalue in a "
"constant expression", build_fold_indirect_ref (sub),
TREE_TYPE (t));
*non_constant_p = true;
tree sub = op0;
STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR)
{
gcc_assert (!same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */
if (!ctx->quiet)
error ("accessing value of %qE through a %qT glvalue in a "
"constant expression", build_fold_indirect_ref (sub),
TREE_TYPE (t));
*non_constant_p = true;
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
that the whole object is constant and then return an empty
CONSTRUCTOR. */
@ -2473,14 +2486,6 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
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;
}