https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91987

--- Comment #3 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 4 Oct 2019, jakub at gcc dot gnu.org wrote:

> 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);
>         }

Ick.  I'd say we should unconditionally guard the transform
with the appropriate TREE_SIDE_EFFECTS check?

> 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?

You need to emit an aggregate copy, don't you?  Consider

int i;

void fun (int i, int j)
{
  assert (i == 0 && j == 1);
}

and

i = 0;
fun (i, (i = 1, 5));

so you cannot gimplify to the post-call sequence.  For the
aggregate case it might be

fun (S &a, S &b)

so handling of

fun (c, c = {})

needs a temporary anyways?

Reply via email to