https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
--- Comment #7 from Marek Polacek <mpolacek at gcc dot gnu.org> --- I think the problem is that we create something 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()> in build_over_call: 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); so the same TARGET_EXPR is used in both operands of the COMPOUND_EXPR, and in op0 we're taking its address 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. But it cannot be elided so we crash later. cp_genericize_r could see if a TARGET_EXPR is wrapped in & and reset TARGET_EXPR_ELIDING_P if so. That would certainly fix it but whether that's the right fix, I'm not sure.