@@ -517,6 +517,28 @@ d_save_expr (tree exp)
517
517
return exp ;
518
518
}
519
519
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
+
520
542
/* Build an unary op CODE to the expression ARG. If the expression can be
521
543
broken down so that the operation is applied only to the part whose value we
522
544
care about, then handle lowering to keep lvalues trivial. */
@@ -532,21 +554,7 @@ build_unary_op (tree_code code, tree type, tree arg)
532
554
return compound_expr (TREE_OPERAND (arg, 0 ), result);
533
555
}
534
556
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);
550
558
551
559
if (code == ADDR_EXPR)
552
560
{
@@ -587,6 +595,16 @@ stabilize_expr2 (tree *valuep)
587
595
|| VOID_TYPE_P (TREE_TYPE (expr)))
588
596
return NULL_TREE;
589
597
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
+
590
608
tree init = force_target_expr (expr);
591
609
*valuep = TARGET_EXPR_SLOT (init);
592
610
@@ -929,13 +947,10 @@ build_struct_comparison (tree_code code, StructDeclaration *sd,
929
947
return build_boolop (code, integer_zero_node, integer_zero_node);
930
948
931
949
/* 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);
934
952
tree result;
935
953
936
- t1 = d_save_expr (t1);
937
- t2 = d_save_expr (t2);
938
-
939
954
/* Bitwise comparison of structs not returned in memory may not work
940
955
due to data holes loosing its zero padding upon return.
941
956
As a heuristic, small structs are not compared using memcmp either. */
@@ -1337,6 +1352,12 @@ component_ref (tree object, tree field)
1337
1352
if (error_operand_p (object) || error_operand_p (field))
1338
1353
return error_mark_node;
1339
1354
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
+
1340
1361
gcc_assert (TREE_CODE (field) == FIELD_DECL);
1341
1362
1342
1363
/* If the FIELD is from an anonymous aggregate, generate a reference
@@ -1359,8 +1380,14 @@ component_ref (tree object, tree field)
1359
1380
tree
1360
1381
build_assign (tree_code code, tree lhs, tree rhs)
1361
1382
{
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);
1364
1391
1365
1392
/* If initializing the LHS using a function that returns via NRVO. */
1366
1393
if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
@@ -1388,9 +1415,7 @@ build_assign (tree_code code, tree lhs, tree rhs)
1388
1415
}
1389
1416
}
1390
1417
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);
1394
1419
}
1395
1420
1396
1421
/* Build an assignment expression of lvalue LHS from value RHS. */
@@ -1558,7 +1583,11 @@ indirect_ref (tree type, tree exp)
1558
1583
return exp ;
1559
1584
1560
1585
/* 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
+ }
1562
1591
1563
1592
if (TREE_CODE (TREE_TYPE (exp )) == REFERENCE_TYPE)
1564
1593
exp = fold_build1 (INDIRECT_REF, type, exp );
@@ -1568,7 +1597,7 @@ indirect_ref (tree type, tree exp)
1568
1597
exp = build_deref (exp );
1569
1598
}
1570
1599
1571
- return compound_expr (init, exp ) ;
1600
+ return exp ;
1572
1601
}
1573
1602
1574
1603
/* Returns indirect reference of EXP, which must be a pointer type. */
@@ -1580,7 +1609,11 @@ build_deref (tree exp)
1580
1609
return exp ;
1581
1610
1582
1611
/* 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
+ }
1584
1617
1585
1618
gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp )));
1586
1619
@@ -1589,7 +1622,7 @@ build_deref (tree exp)
1589
1622
else
1590
1623
exp = build_fold_indirect_ref (exp );
1591
1624
1592
- return compound_expr (init, exp ) ;
1625
+ return exp ;
1593
1626
}
1594
1627
1595
1628
/* Builds pointer offset expression PTR[INDEX]. */
0 commit comments