@@ -38,13 +38,25 @@ void goto_convertt::remove_assignment(
3838 side_effect_exprt &expr,
3939 goto_programt &dest,
4040 bool result_is_used,
41+ bool address_taken,
4142 const irep_idt &mode)
4243{
4344 const irep_idt statement=expr.get_statement ();
4445
46+ optionalt<exprt> replacement_expr_opt;
47+
4548 if (statement==ID_assign)
4649 {
4750 auto &old_assignment = to_side_effect_expr_assign (expr);
51+
52+ if (result_is_used && !address_taken && needs_cleaning (old_assignment.lhs ()))
53+ {
54+ if (!old_assignment.rhs ().is_constant ())
55+ make_temp_symbol (old_assignment.rhs (), " assign" , dest, mode);
56+
57+ replacement_expr_opt = old_assignment.rhs ();
58+ }
59+
4860 exprt new_lhs = skip_typecast (old_assignment.lhs ());
4961 exprt new_rhs =
5062 typecast_exprt::conditional_cast (old_assignment.rhs (), new_lhs.type ());
@@ -113,10 +125,17 @@ void goto_convertt::remove_assignment(
113125 rhs.type () = to_binary_expr (expr).op0 ().type ();
114126 rhs.add_source_location () = expr.source_location ();
115127
128+ if (
129+ result_is_used && !address_taken &&
130+ needs_cleaning (to_binary_expr (expr).op0 ()))
131+ {
132+ make_temp_symbol (rhs, " assign" , dest, mode);
133+ replacement_expr_opt = rhs;
134+ }
135+
116136 exprt new_lhs = skip_typecast (to_binary_expr (expr).op0 ());
117137 rhs = typecast_exprt::conditional_cast (rhs, new_lhs.type ());
118138 rhs.add_source_location () = expr.source_location ();
119-
120139 code_assignt assignment (new_lhs, rhs);
121140 assignment.add_source_location ()=expr.source_location ();
122141
@@ -126,7 +145,13 @@ void goto_convertt::remove_assignment(
126145 UNREACHABLE;
127146
128147 // revert assignment in the expression to its LHS
129- if (result_is_used)
148+ if (replacement_expr_opt.has_value ())
149+ {
150+ exprt new_lhs =
151+ typecast_exprt::conditional_cast (*replacement_expr_opt, expr.type ());
152+ expr.swap (new_lhs);
153+ }
154+ else if (result_is_used)
130155 {
131156 exprt lhs = to_binary_expr (expr).op0 ();
132157 // assign_* statements can have an lhs operand with a different type than
@@ -556,7 +581,8 @@ void goto_convertt::remove_side_effect(
556581 side_effect_exprt &expr,
557582 goto_programt &dest,
558583 const irep_idt &mode,
559- bool result_is_used)
584+ bool result_is_used,
585+ bool address_taken)
560586{
561587 const irep_idt &statement=expr.get_statement ();
562588
@@ -575,7 +601,7 @@ void goto_convertt::remove_side_effect(
575601 statement==ID_assign_ashr ||
576602 statement==ID_assign_shl ||
577603 statement==ID_assign_mod)
578- remove_assignment (expr, dest, result_is_used, mode);
604+ remove_assignment (expr, dest, result_is_used, address_taken, mode);
579605 else if (statement==ID_postincrement ||
580606 statement==ID_postdecrement)
581607 remove_post (expr, dest, mode, result_is_used);
0 commit comments