* constexpr.c (cxx_eval_store_expression): Delay target evaluation.
From-SVN: r272431
This commit is contained in:
parent
043666e095
commit
d0aa42d276
@ -1,3 +1,7 @@
|
|||||||
|
2019-06-18 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
* constexpr.c (cxx_eval_store_expression): Delay target evaluation.
|
||||||
|
|
||||||
2019-06-18 Jason Merrill <jason@redhat.com>
|
2019-06-18 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* constexpr.c (eval_and_check_array_index): Split out from...
|
* constexpr.c (eval_and_check_array_index): Split out from...
|
||||||
|
@ -3747,22 +3747,18 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
|||||||
if (*non_constant_p)
|
if (*non_constant_p)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
target = cxx_eval_constant_expression (ctx, target,
|
|
||||||
true,
|
|
||||||
non_constant_p, overflow_p);
|
|
||||||
if (*non_constant_p)
|
|
||||||
return t;
|
|
||||||
|
|
||||||
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type))
|
bool evaluated = false;
|
||||||
|
if (lval)
|
||||||
{
|
{
|
||||||
/* For initialization of an empty base, the original target will be
|
/* If we want to return a reference to the target, we need to evaluate it
|
||||||
*(base*)this, which the above evaluation resolves to the object
|
as a whole; otherwise, only evaluate the innermost piece to avoid
|
||||||
argument, which has the derived type rather than the base type. In
|
building up unnecessary *_REFs. */
|
||||||
this situation, just evaluate the initializer and return, since
|
target = cxx_eval_constant_expression (ctx, target, true,
|
||||||
there's no actual data to store. */
|
non_constant_p, overflow_p);
|
||||||
gcc_assert (is_empty_class (type));
|
evaluated = true;
|
||||||
return cxx_eval_constant_expression (ctx, init, false,
|
if (*non_constant_p)
|
||||||
non_constant_p, overflow_p);
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the underlying variable. */
|
/* Find the underlying variable. */
|
||||||
@ -3792,7 +3788,17 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
object = probe;
|
if (evaluated)
|
||||||
|
object = probe;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
probe = cxx_eval_constant_expression (ctx, probe, true,
|
||||||
|
non_constant_p, overflow_p);
|
||||||
|
evaluated = true;
|
||||||
|
if (*non_constant_p)
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3948,7 +3954,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
|||||||
new_ctx.object = target;
|
new_ctx.object = target;
|
||||||
init = cxx_eval_constant_expression (&new_ctx, init, false,
|
init = cxx_eval_constant_expression (&new_ctx, init, false,
|
||||||
non_constant_p, overflow_p);
|
non_constant_p, overflow_p);
|
||||||
if (target == object)
|
if (ctors->is_empty())
|
||||||
/* The hash table might have moved since the get earlier. */
|
/* The hash table might have moved since the get earlier. */
|
||||||
valp = ctx->values->get (object);
|
valp = ctx->values->get (object);
|
||||||
}
|
}
|
||||||
@ -3961,6 +3967,17 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
|||||||
{
|
{
|
||||||
/* An outer ctx->ctor might be pointing to *valp, so replace
|
/* An outer ctx->ctor might be pointing to *valp, so replace
|
||||||
its contents. */
|
its contents. */
|
||||||
|
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
|
||||||
|
TREE_TYPE (*valp)))
|
||||||
|
{
|
||||||
|
/* For initialization of an empty base, the original target will be
|
||||||
|
*(base*)this, evaluation of which resolves to the object
|
||||||
|
argument, which has the derived type rather than the base type. In
|
||||||
|
this situation, just evaluate the initializer and return, since
|
||||||
|
there's no actual data to store. */
|
||||||
|
gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
|
||||||
|
return init;
|
||||||
|
}
|
||||||
CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
|
CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
|
||||||
TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
|
TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
|
||||||
TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
|
TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user