diff options
author | Jason Merrill <jason@redhat.com> | 2020-04-04 11:04:55 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-04 11:06:31 -0400 |
commit | 9f143008c73c60e02634d6b433139a035ef7bb65 (patch) | |
tree | dde2a0566499fe03a7c93a2f784d3b3cad280477 /gcc/cp/expr.c | |
parent | 2523d721cfc861a3abea6e97736446c99ba8b52d (diff) | |
download | gcc-9f143008c73c60e02634d6b433139a035ef7bb65.zip gcc-9f143008c73c60e02634d6b433139a035ef7bb65.tar.gz gcc-9f143008c73c60e02634d6b433139a035ef7bb65.tar.bz2 |
c++: Fix reuse of class constants [PR94453]
The testcase hit an ICE trying to expand a TARGET_EXPR temporary cached from
the other lambda-expression. This patch fixes this in two ways:
1) Avoid reusing a TARGET_EXPR from another function.
2) Avoid ending up with a TARGET_EXPR at all; the use of 'p' had become
<TARGET_EXPR<NON_LVALUE_EXPR<TARGET_EXPR ...>>>, which doesn't make any
sense.
gcc/cp/ChangeLog
2020-04-04 Jason Merrill <jason@redhat.com>
PR c++/94453
* constexpr.c (maybe_constant_value): Use break_out_target_exprs.
* expr.c (mark_use) [VIEW_CONVERT_EXPR]: Don't wrap a TARGET_EXPR in
NON_LVALUE_EXPR.
Diffstat (limited to 'gcc/cp/expr.c')
-rw-r--r-- | gcc/cp/expr.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 04e4418..9b53570 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -195,11 +195,23 @@ mark_use (tree expr, bool rvalue_p, bool read_p, tree nop = RECUR (op); if (nop == error_mark_node) return error_mark_node; - TREE_OPERAND (expr, 0) = nop; - /* If we're replacing a DECL with a constant, we also need to change - the TREE_CODE of the location wrapper. */ - if (op != nop && rvalue_p) - TREE_SET_CODE (expr, NON_LVALUE_EXPR); + else if (op == nop) + /* No change. */; + else if (DECL_P (nop) || CONSTANT_CLASS_P (nop)) + { + /* Reuse the location wrapper. */ + TREE_OPERAND (expr, 0) = nop; + /* If we're replacing a DECL with a constant, we also need to + change the TREE_CODE of the location wrapper. */ + if (rvalue_p) + TREE_SET_CODE (expr, NON_LVALUE_EXPR); + } + else + { + /* Drop the location wrapper. */ + expr = nop; + protected_set_expr_location (expr, loc); + } return expr; } gcc_fallthrough(); |