This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/84322] -fstrong-eval-order violated on assignment with function call


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
We have:
       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_formal_tmp_var (op1, pre_p);
but lvalue_has_side_effects does nothing if TREE_SIDE_EFFECTS is 0:
static bool
lvalue_has_side_effects (tree e)
{
  if (!TREE_SIDE_EFFECTS (e))
    return false;
  while (handled_component_p (e))
    {
      if (TREE_CODE (e) == ARRAY_REF
          && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
        return true;
      e = TREE_OPERAND (e, 0);
    }
  if (DECL_P (e))
    /* Just naming a variable has no side-effects.  */
    return false;
  else if (INDIRECT_REF_P (e))
    /* Similarly, indirection has no side-effects.  */
    return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
  else
    /* For anything else, trust TREE_SIDE_EFFECTS.  */
    return TREE_SIDE_EFFECTS (e);
}

A mere read from memory is not accounted for in TREE_SIDE_EFFECTS, but as the
testcase shows, we probably need to consider it as a side-effect too.

What about:
extern int a[10];
int g ();

void
f ()
{
  *(a + a[1]) = g ();
}

or any other arbitrary expressions on the LHS which can read from
needs_to_live_in_memory variables?

I'm also wondering about
        if (!error_operand_p (op0)
            && !error_operand_p (op1)
            && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
                || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
            && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
          TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
                                              TREE_TYPE (op0), op1);
after which the P0145 checks aren't done, can it ever happen that op1 is a
CALL_EXPR in this case?

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]