aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-08-15 17:55:19 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-08-15 17:55:19 -0400
commit7148dede8a84e17cc0b00190d76fabbc1a717654 (patch)
treef160ffecb6dcfc5746b9c4a402681d65b1e664fd /gcc/cp/tree.c
parentd321551cea11f27a9afd67ece9bbda095a579950 (diff)
downloadgcc-7148dede8a84e17cc0b00190d76fabbc1a717654.zip
gcc-7148dede8a84e17cc0b00190d76fabbc1a717654.tar.gz
gcc-7148dede8a84e17cc0b00190d76fabbc1a717654.tar.bz2
PR c++/90393 - ICE with thow in ?:
My previous patch for 64372 was incomplete: it only stopped making the non-throw argument into an rvalue, lvalue_kind still considered the ?: expression to be an rvalue, leaving us worse than before. PR c++/64372, DR 1560 - Gratuitous lvalue-to-rvalue conversion in ?: * tree.c (lvalue_kind): Handle throw in one arm. * typeck.c (rationalize_conditional_expr): Likewise. (cp_build_modify_expr): Likewise. From-SVN: r274550
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index bca9210..17a4df3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -236,10 +236,23 @@ lvalue_kind (const_tree ref)
gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
goto default_;
}
- op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
- ? TREE_OPERAND (ref, 1)
- : TREE_OPERAND (ref, 0));
- op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 2));
+ {
+ tree op1 = TREE_OPERAND (ref, 1);
+ if (!op1) op1 = TREE_OPERAND (ref, 0);
+ tree op2 = TREE_OPERAND (ref, 2);
+ op1_lvalue_kind = lvalue_kind (op1);
+ op2_lvalue_kind = lvalue_kind (op2);
+ if (!op1_lvalue_kind != !op2_lvalue_kind)
+ {
+ /* The second or the third operand (but not both) is a
+ throw-expression; the result is of the type
+ and value category of the other. */
+ if (op1_lvalue_kind && TREE_CODE (op2) == THROW_EXPR)
+ op2_lvalue_kind = op1_lvalue_kind;
+ else if (op2_lvalue_kind && TREE_CODE (op1) == THROW_EXPR)
+ op1_lvalue_kind = op2_lvalue_kind;
+ }
+ }
break;
case MODOP_EXPR: