diff options
author | Jason Merrill <jason@redhat.com> | 2019-08-15 17:55:19 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-08-15 17:55:19 -0400 |
commit | 7148dede8a84e17cc0b00190d76fabbc1a717654 (patch) | |
tree | f160ffecb6dcfc5746b9c4a402681d65b1e664fd /gcc/cp/tree.c | |
parent | d321551cea11f27a9afd67ece9bbda095a579950 (diff) | |
download | gcc-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.c | 21 |
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: |