https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91987
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So for the shifts we'd need additionally:
--- gcc/fold-const.c.jj 2019-09-02 15:29:34.548515139 +0200
+++ gcc/fold-const.c 2019-10-04 10:44:23.319883187 +0200
@@ -9447,16 +9447,23 @@ fold_binary_loc (location_t loc, enum tr
if (TREE_CODE (arg0) == COMPOUND_EXPR)
{
tem = fold_build2_loc (loc, code, type,
- fold_convert_loc (loc, TREE_TYPE (op0),
- TREE_OPERAND (arg0, 1)), op1);
+ fold_convert_loc (loc, TREE_TYPE (op0),
+ TREE_OPERAND (arg0, 1)),
+ op1);
return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
tem);
}
- if (TREE_CODE (arg1) == COMPOUND_EXPR)
+ if (TREE_CODE (arg1) == COMPOUND_EXPR
+ && (flag_strong_eval_order != 2
+ /* C++17 disallows this canonicalization for shifts. */
+ || (code != LSHIFT_EXPR
+ && code != RSHIFT_EXPR
+ && code != LROTATE_EXPR
+ && code != RROTATE_EXPR)))
{
tem = fold_build2_loc (loc, code, type, op0,
- fold_convert_loc (loc, TREE_TYPE (op1),
- TREE_OPERAND (arg1, 1)));
+ fold_convert_loc (loc, TREE_TYPE (op1),
+ TREE_OPERAND (arg1, 1)));
return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
tem);
}
One thing I'm worried about are the special cases where we enforce some
argument order, evaluate one argument before the other or vice versa.
For is_gimple_reg_type args it can be just a matter of forcing it into an
SSA_NAME or a new VAR_DECL, but if a function argument is a structure,
struct S { int a, b; } c = { 1, 2 };
fun (c, (c.b = 3, 5);
and fun is one of the magic one that enforce operand ordering and the first
argument needs to be sequenced before the second, what can we do?