@@ -517,6 +517,28 @@ d_save_expr (tree exp)
517517 return exp;
518518}
519519
520+ /* Adjust EXPR so that it is a valid lvalue, and can be evaluated multiple times
521+ if it has any side effects. */
522+
523+ static tree
524+ compound_lvalue (tree expr)
525+ {
526+ const tree_code code = TREE_CODE (expr);
527+
528+ if (code == MODIFY_EXPR || code == PREINCREMENT_EXPR
529+ || code == PREDECREMENT_EXPR)
530+ {
531+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0 )))
532+ expr = build2 (TREE_CODE (expr), TREE_TYPE (expr),
533+ stabilize_reference (TREE_OPERAND (expr, 0 )),
534+ TREE_OPERAND (expr, 1 ));
535+
536+ return compound_expr (expr, TREE_OPERAND (expr, 0 ));
537+ }
538+
539+ return expr;
540+ }
541+
520542/* Build an unary op CODE to the expression ARG. If the expression can be
521543 broken down so that the operation is applied only to the part whose value we
522544 care about, then handle lowering to keep lvalues trivial. */
@@ -532,21 +554,7 @@ build_unary_op (tree_code code, tree type, tree arg)
532554 return compound_expr (TREE_OPERAND (arg, 0 ), result);
533555 }
534556
535- /* Given (e1 = e2), (++e1), or (--e1), convert 'e1' into an lvalue. */
536- if (TREE_CODE (arg) == MODIFY_EXPR
537- || TREE_CODE (arg) == PREINCREMENT_EXPR
538- || TREE_CODE (arg) == PREDECREMENT_EXPR)
539- {
540- if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0 )))
541- {
542- arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
543- stabilize_reference (TREE_OPERAND (arg, 0 )),
544- TREE_OPERAND (arg, 1 ));
545- gcc_unreachable ();
546- }
547- return build_unary_op (code, type,
548- compound_expr (arg, TREE_OPERAND (arg, 0 )));
549- }
557+ arg = compound_lvalue (arg);
550558
551559 if (code == ADDR_EXPR)
552560 {
@@ -587,6 +595,16 @@ stabilize_expr2 (tree *valuep)
587595 || VOID_TYPE_P (TREE_TYPE (expr)))
588596 return NULL_TREE;
589597
598+ /* Stabilize only the right hand side of compound expressions. */
599+ if (TREE_CODE (expr) == COMPOUND_EXPR)
600+ {
601+ tree lhs = TREE_OPERAND (expr, 0 );
602+ tree rhs = TREE_OPERAND (expr, 1 );
603+ lhs = compound_expr (lhs, stabilize_expr2 (&rhs));
604+ *valuep = rhs;
605+ return lhs;
606+ }
607+
590608 tree init = force_target_expr (expr);
591609 *valuep = TARGET_EXPR_SLOT (init);
592610
@@ -929,13 +947,10 @@ build_struct_comparison (tree_code code, StructDeclaration *sd,
929947 return build_boolop (code, integer_zero_node, integer_zero_node);
930948
931949 /* Make temporaries to prevent multiple evaluations. */
932- tree t1init = stabilize_expr (&t1);
933- tree t2init = stabilize_expr (&t2);
950+ tree t1init = stabilize_expr2 (&t1);
951+ tree t2init = stabilize_expr2 (&t2);
934952 tree result;
935953
936- t1 = d_save_expr (t1);
937- t2 = d_save_expr (t2);
938-
939954 /* Bitwise comparison of structs not returned in memory may not work
940955 due to data holes loosing its zero padding upon return.
941956 As a heuristic, small structs are not compared using memcmp either. */
@@ -1337,6 +1352,12 @@ component_ref (tree object, tree field)
13371352 if (error_operand_p (object) || error_operand_p (field))
13381353 return error_mark_node;
13391354
1355+ if (TREE_CODE (object) == COMPOUND_EXPR)
1356+ {
1357+ tree result = component_ref (TREE_OPERAND (object, 1 ), field);
1358+ return compound_expr (TREE_OPERAND (object, 0 ), result);
1359+ }
1360+
13401361 gcc_assert (TREE_CODE (field) == FIELD_DECL);
13411362
13421363 /* If the FIELD is from an anonymous aggregate, generate a reference
@@ -1359,8 +1380,14 @@ component_ref (tree object, tree field)
13591380tree
13601381build_assign (tree_code code, tree lhs, tree rhs)
13611382{
1362- tree init = stabilize_expr (&lhs);
1363- init = compound_expr (init, stabilize_expr (&rhs));
1383+ /* Handle control structure constructs used as lvalues. */
1384+ if (TREE_CODE (lhs) == COMPOUND_EXPR)
1385+ {
1386+ tree result = build_assign (code, TREE_OPERAND (lhs, 1 ), rhs);
1387+ return compound_expr (TREE_OPERAND (lhs, 0 ), result);
1388+ }
1389+
1390+ lhs = compound_lvalue (lhs);
13641391
13651392 /* If initializing the LHS using a function that returns via NRVO. */
13661393 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
@@ -1388,9 +1415,7 @@ build_assign (tree_code code, tree lhs, tree rhs)
13881415 }
13891416 }
13901417
1391- tree result = fold_build2_loc (input_location, code,
1392- TREE_TYPE (lhs), lhs, rhs);
1393- return compound_expr (init, result);
1418+ return fold_build2_loc (input_location, code, TREE_TYPE (lhs), lhs, rhs);
13941419}
13951420
13961421/* Build an assignment expression of lvalue LHS from value RHS. */
@@ -1558,7 +1583,11 @@ indirect_ref (tree type, tree exp)
15581583 return exp;
15591584
15601585 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1561- tree init = stabilize_expr2 (&exp);
1586+ if (TREE_CODE (exp) == COMPOUND_EXPR)
1587+ {
1588+ tree result = indirect_ref (type, TREE_OPERAND (exp, 1 ));
1589+ return compound_expr (TREE_OPERAND (exp, 0 ), result);
1590+ }
15621591
15631592 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
15641593 exp = fold_build1 (INDIRECT_REF, type, exp);
@@ -1568,7 +1597,7 @@ indirect_ref (tree type, tree exp)
15681597 exp = build_deref (exp);
15691598 }
15701599
1571- return compound_expr (init, exp) ;
1600+ return exp;
15721601}
15731602
15741603/* Returns indirect reference of EXP, which must be a pointer type. */
@@ -1580,7 +1609,11 @@ build_deref (tree exp)
15801609 return exp;
15811610
15821611 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1583- tree init = stabilize_expr2 (&exp);
1612+ if (TREE_CODE (exp) == COMPOUND_EXPR)
1613+ {
1614+ tree result = build_deref (TREE_OPERAND (exp, 1 ));
1615+ return compound_expr (TREE_OPERAND (exp, 0 ), result);
1616+ }
15841617
15851618 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
15861619
@@ -1589,7 +1622,7 @@ build_deref (tree exp)
15891622 else
15901623 exp = build_fold_indirect_ref (exp);
15911624
1592- return compound_expr (init, exp) ;
1625+ return exp;
15931626}
15941627
15951628/* Builds pointer offset expression PTR[INDEX]. */
0 commit comments