On 3/10/25 6:31 PM, Marek Polacek wrote:
build_over_call has:

          t = build2 (MODIFY_EXPR, void_type_node,
                      build2 (MEM_REF, array_type, arg0, alias_set),
                      build2 (MEM_REF, array_type, arg, alias_set));
          val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);

which creates an expression that can look like:

   d = MEM <unsigned char[4]> [(struct A *)&TARGET_EXPR <D.2894, foo()]
     = MEM <unsigned char[4]> [(struct A *)(const struct A &) &e],
       TARGET_EXPR <D.2894, foo()>

that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its
address is taken in the left-hand side operand, so it can't be elided.
But set_target_expr_eliding simply recurses on the second operand of
a COMPOUND_EXPR and marks the TARGET_EXPR as eliding.  This then causes
a crash.

The problem is with build_over_call returning a prvalue (TARGET_EXPR) when operator= should return an lvalue.

I guess the issue is the call to cp_build_fold_indirect_ref (argarray[0]) messing up the value category.

Perhaps the do_fold code in that function should only happen if the result is an lvalue.

Jason

Reply via email to