@@ -111,7 +111,7 @@ static optionalt<exprt> get_array(
111
111
const array_string_exprt &arr,
112
112
const array_poolt &array_pool);
113
113
114
- static exprt substitute_array_access (
114
+ static optionalt< exprt> substitute_array_access (
115
115
const index_exprt &index_expr,
116
116
symbol_generatort &symbol_generator,
117
117
const bool left_propagate);
@@ -1155,16 +1155,22 @@ static exprt substitute_array_access(
1155
1155
symbol_generatort &symbol_generator,
1156
1156
const bool left_propagate)
1157
1157
{
1158
- // Substitute recursively in branches of conditional expressions
1159
- const exprt true_case = substitute_array_access (
1160
- index_exprt (if_expr.true_case (), index ), symbol_generator, left_propagate);
1161
- const exprt false_case = substitute_array_access (
1162
- index_exprt (if_expr.false_case (), index ), symbol_generator, left_propagate);
1158
+ exprt true_index = index_exprt (if_expr.true_case (), index );
1159
+ exprt false_index = index_exprt (if_expr.false_case (), index );
1163
1160
1164
- return if_exprt (if_expr.cond (), true_case, false_case);
1161
+ // Substitute recursively in branches of conditional expressions
1162
+ optionalt<exprt> substituted_true_case =
1163
+ substitute_array_access (true_index, symbol_generator, left_propagate);
1164
+ optionalt<exprt> substituted_false_case =
1165
+ substitute_array_access (false_index, symbol_generator, left_propagate);
1166
+
1167
+ return if_exprt (
1168
+ if_expr.cond (),
1169
+ substituted_true_case ? *substituted_true_case : true_index,
1170
+ substituted_false_case ? *substituted_false_case : false_index);
1165
1171
}
1166
1172
1167
- static exprt substitute_array_access (
1173
+ static optionalt< exprt> substitute_array_access (
1168
1174
const index_exprt &index_expr,
1169
1175
symbol_generatort &symbol_generator,
1170
1176
const bool left_propagate)
@@ -1187,7 +1193,7 @@ static exprt substitute_array_access(
1187
1193
std::string (
1188
1194
" in case the array is unknown, it should be a symbol or nil, id: " ) +
1189
1195
id2string (array.id ()));
1190
- return index_expr ;
1196
+ return {} ;
1191
1197
}
1192
1198
1193
1199
// / Auxiliary function for substitute_array_access
@@ -1198,14 +1204,19 @@ static void substitute_array_access_in_place(
1198
1204
symbol_generatort &symbol_generator,
1199
1205
const bool left_propagate)
1200
1206
{
1201
- if (const auto index_expr = expr_try_dynamic_cast<index_exprt>(expr))
1207
+ // Recurse down structure and modify on the way.
1208
+ for (auto it = expr.depth_begin (), itend = expr.depth_end (); it != itend; ++it)
1202
1209
{
1203
- expr =
1204
- substitute_array_access (*index_expr, symbol_generator, left_propagate);
1205
- }
1210
+ if (const auto index_expr = expr_try_dynamic_cast<index_exprt>(*it))
1211
+ {
1212
+ optionalt<exprt> result =
1213
+ substitute_array_access (*index_expr, symbol_generator, left_propagate);
1206
1214
1207
- for (auto &op : expr.operands ())
1208
- substitute_array_access_in_place (op, symbol_generator, left_propagate);
1215
+ // Only perform a write when we have something changed.
1216
+ if (result)
1217
+ it.mutate () = *result;
1218
+ }
1219
+ }
1209
1220
}
1210
1221
1211
1222
// / Create an equivalent expression where array accesses and 'with' expressions
0 commit comments