Commit dfffecb8 by Jason Merrill

c++: Fix static initialization from <=>.

Constant evaluation of genericize_spaceship produced a CONSTRUCTOR, which we
then wanted to bind to a reference, which we can't do.  So wrap the result
in a TARGET_EXPR so we get something with an address.

We also need to handle treating the result of cxx_eval_binary_expression as
a glvalue for SPACESHIP_EXPR.

My earlier change to add uid_sensitive to maybe_constant_value was wrong; we
don't even look at the cache when manifestly_const_eval, and I failed to
adjust the later call to cxx_eval_outermost_constant_expr.

gcc/cp/ChangeLog
2020-02-11  Jason Merrill  <jason@redhat.com>

	PR c++/93650
	PR c++/90691
	* constexpr.c (maybe_constant_value): Correct earlier change.
	(cxx_eval_binary_expression) [SPACESHIP_EXPR]: Pass lval through.
	* method.c (genericize_spaceship): Wrap result in TARGET_EXPR.
parent a6ee556c
2020-02-11 Jason Merrill <jason@redhat.com>
PR c++/93650
PR c++/90691
* constexpr.c (maybe_constant_value): Correct earlier change.
(cxx_eval_binary_expression) [SPACESHIP_EXPR]: Pass lval through.
* method.c (genericize_spaceship): Wrap result in TARGET_EXPR.
2020-02-12 Patrick Palka <ppalka@redhat.com>
PR c++/69448
......
......@@ -2834,7 +2834,7 @@ cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
bool /*lval*/,
bool lval,
bool *non_constant_p, bool *overflow_p)
{
tree r = NULL_TREE;
......@@ -2902,7 +2902,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
else if (code == SPACESHIP_EXPR)
{
r = genericize_spaceship (type, lhs, rhs);
r = cxx_eval_constant_expression (ctx, r, false, non_constant_p,
r = cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
overflow_p);
}
......@@ -6686,13 +6686,11 @@ maybe_constant_value (tree t, tree decl, bool manifestly_const_eval,
r = unshare_expr_without_location (r);
protected_set_expr_location (r, EXPR_LOCATION (t));
}
if (r != t || TREE_CONSTANT (t) || !manifestly_const_eval)
return r;
/* If we cached this as non-constant and we need a constant value, try
again; we might have failed before due to UID_SENSITIVE. */
return r;
}
r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl);
r = cxx_eval_outermost_constant_expr (t, true, true, false, false,
decl, uid_sensitive);
gcc_checking_assert (r == t
|| CONVERT_EXPR_P (t)
|| TREE_CODE (t) == VIEW_CONVERT_EXPR
......
......@@ -1075,6 +1075,9 @@ genericize_spaceship (tree type, tree op0, tree op1)
comp = fold_build2 (EQ_EXPR, boolean_type_node, op0, op1);
r = fold_build3 (COND_EXPR, type, comp, eq, r);
/* Wrap the whole thing in a TARGET_EXPR like build_conditional_expr_1. */
r = get_target_expr (r);
return r;
}
......
// PR c++/93650
// { dg-do compile { target c++2a } }
namespace std {
using type = enum _Ord { less };
class strong_ordering {
type _M_value;
constexpr strong_ordering(_Ord) : _M_value() {}
static const strong_ordering less;
static strong_ordering equal;
static strong_ordering greater;
} constexpr strong_ordering::less(_Ord::less);
auto v = 1 <=> 2;
}
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