diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-10 14:05:06 +0100 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-11 09:17:42 +0100 |
commit | dfffecb802681fbdb56629d3bdd96491ac660be0 (patch) | |
tree | c39d43ce40c0895261f2d7993ac4b5a8c783bcba /gcc | |
parent | a6ee556c7659877bb59b719f11ca2153e86ded59 (diff) | |
download | gcc-dfffecb802681fbdb56629d3bdd96491ac660be0.zip gcc-dfffecb802681fbdb56629d3bdd96491ac660be0.tar.gz gcc-dfffecb802681fbdb56629d3bdd96491ac660be0.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 12 | ||||
-rw-r--r-- | gcc/cp/method.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr2.C | 14 |
4 files changed, 30 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bf7bf5f..f4b0479 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +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 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 6495cf8..bf7a264 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index fef19e1..cfc37bc 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr2.C new file mode 100644 index 0000000..02f92b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr2.C @@ -0,0 +1,14 @@ +// 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; +} |