@@ -517,6 +517,26 @@ d_save_expr (tree exp)
517
517
return exp ;
518
518
}
519
519
520
+ /* Adjust LVALUE, a MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR, so
521
+ that it is a valid lvalue, and can be evaluated multiple times. */
522
+
523
+ static tree
524
+ genericize_compound_lvalue (tree lvalue)
525
+ {
526
+ const tree_code code = TREE_CODE (lvalue);
527
+
528
+ gcc_assert (code == MODIFY_EXPR
529
+ || code == PREINCREMENT_EXPR
530
+ || code == PREDECREMENT_EXPR);
531
+
532
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0 )))
533
+ lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
534
+ stabilize_reference (TREE_OPERAND (lvalue, 0 )),
535
+ TREE_OPERAND (lvalue, 1 ));
536
+
537
+ return compound_expr (lvalue, TREE_OPERAND (lvalue, 0 ));
538
+ }
539
+
520
540
/* Build an unary op CODE to the expression ARG. If the expression can be
521
541
broken down so that the operation is applied only to the part whose value we
522
542
care about, then handle lowering to keep lvalues trivial. */
@@ -536,17 +556,7 @@ build_unary_op (tree_code code, tree type, tree arg)
536
556
if (TREE_CODE (arg) == MODIFY_EXPR
537
557
|| TREE_CODE (arg) == PREINCREMENT_EXPR
538
558
|| 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
- }
559
+ return build_unary_op (code, type, genericize_compound_lvalue (arg));
550
560
551
561
if (code == ADDR_EXPR)
552
562
{
@@ -587,6 +597,16 @@ stabilize_expr2 (tree *valuep)
587
597
|| VOID_TYPE_P (TREE_TYPE (expr)))
588
598
return NULL_TREE;
589
599
600
+ /* Stabilize only the right hand side of compound expressions. */
601
+ if (TREE_CODE (expr) == COMPOUND_EXPR)
602
+ {
603
+ tree lhs = TREE_OPERAND (expr, 0 );
604
+ tree rhs = TREE_OPERAND (expr, 1 );
605
+ lhs = compound_expr (lhs, stabilize_expr2 (&rhs));
606
+ *valuep = rhs;
607
+ return lhs;
608
+ }
609
+
590
610
tree init = force_target_expr (expr);
591
611
*valuep = TARGET_EXPR_SLOT (init);
592
612
@@ -929,13 +949,10 @@ build_struct_comparison (tree_code code, StructDeclaration *sd,
929
949
return build_boolop (code, integer_zero_node, integer_zero_node);
930
950
931
951
/* Make temporaries to prevent multiple evaluations. */
932
- tree t1init = stabilize_expr (&t1);
933
- tree t2init = stabilize_expr (&t2);
952
+ tree t1init = stabilize_expr2 (&t1);
953
+ tree t2init = stabilize_expr2 (&t2);
934
954
tree result;
935
955
936
- t1 = d_save_expr (t1);
937
- t2 = d_save_expr (t2);
938
-
939
956
/* Bitwise comparison of structs not returned in memory may not work
940
957
due to data holes loosing its zero padding upon return.
941
958
As a heuristic, small structs are not compared using memcmp either. */
@@ -1337,6 +1354,12 @@ component_ref (tree object, tree field)
1337
1354
if (error_operand_p (object) || error_operand_p (field))
1338
1355
return error_mark_node;
1339
1356
1357
+ if (TREE_CODE (object) == COMPOUND_EXPR)
1358
+ {
1359
+ tree result = component_ref (TREE_OPERAND (object, 1 ), field);
1360
+ return compound_expr (TREE_OPERAND (object, 0 ), result);
1361
+ }
1362
+
1340
1363
gcc_assert (TREE_CODE (field) == FIELD_DECL);
1341
1364
1342
1365
/* If the FIELD is from an anonymous aggregate, generate a reference
@@ -1359,8 +1382,21 @@ component_ref (tree object, tree field)
1359
1382
tree
1360
1383
build_assign (tree_code code, tree lhs, tree rhs)
1361
1384
{
1362
- tree init = stabilize_expr (&lhs);
1363
- init = compound_expr (init, stabilize_expr (&rhs));
1385
+ /* Handle control structure constructs used as lvalues. */
1386
+ if (TREE_CODE (lhs) == COMPOUND_EXPR)
1387
+ {
1388
+ tree result = build_assign (code, TREE_OPERAND (lhs, 1 ), rhs);
1389
+ return compound_expr (TREE_OPERAND (lhs, 0 ), result);
1390
+ }
1391
+
1392
+ if (TREE_CODE (lhs) == MODIFY_EXPR
1393
+ || TREE_CODE (lhs) == PREINCREMENT_EXPR
1394
+ || TREE_CODE (lhs) == PREDECREMENT_EXPR)
1395
+ lhs = genericize_compound_lvalue (lhs);
1396
+ else if (TREE_CODE (lhs) == COND_EXPR)
1397
+ gcc_unreachable ();
1398
+
1399
+ // tree init = stabilize_expr2 (&lhs);
1364
1400
1365
1401
/* If initializing the LHS using a function that returns via NRVO. */
1366
1402
if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
@@ -1390,7 +1426,8 @@ build_assign (tree_code code, tree lhs, tree rhs)
1390
1426
1391
1427
tree result = fold_build2_loc (input_location, code,
1392
1428
TREE_TYPE (lhs), lhs, rhs);
1393
- return compound_expr (init, result);
1429
+ // return compound_expr (init, result);
1430
+ return result;
1394
1431
}
1395
1432
1396
1433
/* Build an assignment expression of lvalue LHS from value RHS. */
@@ -1558,7 +1595,11 @@ indirect_ref (tree type, tree exp)
1558
1595
return exp ;
1559
1596
1560
1597
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1561
- tree init = stabilize_expr2 (&exp );
1598
+ if (TREE_CODE (exp ) == COMPOUND_EXPR)
1599
+ {
1600
+ tree result = indirect_ref (type, TREE_OPERAND (exp , 1 ));
1601
+ return compound_expr (TREE_OPERAND (exp , 0 ), result);
1602
+ }
1562
1603
1563
1604
if (TREE_CODE (TREE_TYPE (exp )) == REFERENCE_TYPE)
1564
1605
exp = fold_build1 (INDIRECT_REF, type, exp );
@@ -1568,7 +1609,7 @@ indirect_ref (tree type, tree exp)
1568
1609
exp = build_deref (exp );
1569
1610
}
1570
1611
1571
- return compound_expr (init, exp ) ;
1612
+ return exp ;
1572
1613
}
1573
1614
1574
1615
/* Returns indirect reference of EXP, which must be a pointer type. */
@@ -1580,7 +1621,11 @@ build_deref (tree exp)
1580
1621
return exp ;
1581
1622
1582
1623
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1583
- tree init = stabilize_expr2 (&exp );
1624
+ if (TREE_CODE (exp ) == COMPOUND_EXPR)
1625
+ {
1626
+ tree result = build_deref (TREE_OPERAND (exp , 1 ));
1627
+ return compound_expr (TREE_OPERAND (exp , 0 ), result);
1628
+ }
1584
1629
1585
1630
gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp )));
1586
1631
@@ -1589,7 +1634,7 @@ build_deref (tree exp)
1589
1634
else
1590
1635
exp = build_fold_indirect_ref (exp );
1591
1636
1592
- return compound_expr (init, exp ) ;
1637
+ return exp ;
1593
1638
}
1594
1639
1595
1640
/* Builds pointer offset expression PTR[INDEX]. */
0 commit comments