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

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think w normally honor the C++17 rules, it can be seen on
int
foo (int &x, int *&y)
{
  y = &x;
  x++;
  return x;
}

int &
bar (int *p)
{
  return *p;
}

int
main ()
{
  int a = 4;
  int b = 9;
  int *c = &b;
  bar (c) = foo (a, c);
  __builtin_printf ("%d %d %d\n", a, *c, b);
}
which prints 5 5 9 and calls bar after calling foo, including reading the c
pointer from memory.
Bet this is just that *c has no side-effects.
cp_gimplify_expr has for this:
        /* P0145 says that the RHS is sequenced before the LHS.
           gimplify_modify_expr gimplifies the RHS before the LHS, but that
           isn't quite strong enough in two cases:

           1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
           mean it's evaluated after the LHS.

           2) the value calculation of the RHS is also sequenced before the
           LHS, so for scalar assignment we need to preevaluate if the
           RHS could be affected by LHS side-effects even if it has no
           side-effects of its own.  We don't need this for classes because
           class assignment takes its RHS by reference.  */
       else if (flag_strong_eval_order > 1
                && TREE_CODE (*expr_p) == MODIFY_EXPR
                && lvalue_has_side_effects (op0)
                && (TREE_CODE (op1) == CALL_EXPR
                    || (SCALAR_TYPE_P (TREE_TYPE (op1))
                        && !TREE_CONSTANT (op1))))
         TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);

Reply via email to