@@ -113,206 +113,6 @@ struct assignmentt final
113
113
exprt rhs;
114
114
};
115
115
116
- // / Replace "with" (or "update") expressions in the right-hand side of
117
- // / \p assignment by their update values and move the index or member to the
118
- // / left-hand side of \p assignment. This effectively undoes the work that
119
- // / \ref symex_assignt::assign_array and
120
- // / \ref symex_assignt::assign_struct_member have done, but now making use
121
- // / of the index/member that may only be known after renaming to L2 has taken
122
- // / place.
123
- // / \tparam use_update: use update_exprt instead of with_exprt when building
124
- // / expressions that modify components of an array or a struct
125
- // / \param [in, out] state: symbolic execution state to perform renaming
126
- // / \param assignment: an assignment to rewrite
127
- // / \param ns: namespace
128
- // / \return the updated assignment
129
- template <bool use_update>
130
- static assignmentt rewrite_with_to_field_symbols (
131
- goto_symext::statet &state,
132
- assignmentt assignment,
133
- const namespacet &ns)
134
- {
135
- exprt &ssa_rhs = assignment.rhs ;
136
- ssa_exprt &lhs_mod = assignment.lhs ;
137
- if (use_update)
138
- {
139
- while (ssa_rhs.id () == ID_update &&
140
- to_update_expr (ssa_rhs).designator ().size () == 1 &&
141
- (lhs_mod.type ().id () == ID_array ||
142
- lhs_mod.type ().id () == ID_struct ||
143
- lhs_mod.type ().id () == ID_struct_tag))
144
- {
145
- exprt field_sensitive_lhs;
146
- const update_exprt &update = to_update_expr (ssa_rhs);
147
- PRECONDITION (update.designator ().size () == 1 );
148
- const exprt &designator = update.designator ().front ();
149
-
150
- if (lhs_mod.type ().id () == ID_array)
151
- {
152
- field_sensitive_lhs =
153
- index_exprt (lhs_mod, to_index_designator (designator).index ());
154
- }
155
- else
156
- {
157
- field_sensitive_lhs = member_exprt (
158
- lhs_mod,
159
- to_member_designator (designator).get_component_name (),
160
- update.new_value ().type ());
161
- }
162
-
163
- state.field_sensitivity .apply (ns, state, field_sensitive_lhs, true );
164
-
165
- if (field_sensitive_lhs.id () != ID_symbol)
166
- break ;
167
-
168
- ssa_rhs = update.new_value ();
169
- lhs_mod = to_ssa_expr (field_sensitive_lhs);
170
- }
171
- }
172
- else
173
- {
174
- while (
175
- ssa_rhs.id () == ID_with && to_with_expr (ssa_rhs).operands ().size () == 3 &&
176
- (lhs_mod.type ().id () == ID_array || lhs_mod.type ().id () == ID_struct ||
177
- lhs_mod.type ().id () == ID_struct_tag))
178
- {
179
- exprt field_sensitive_lhs;
180
- expr_skeletont lhs_skeleton;
181
- const with_exprt &with_expr = to_with_expr (ssa_rhs);
182
-
183
- if (lhs_mod.type ().id () == ID_array)
184
- {
185
- field_sensitive_lhs = index_exprt (lhs_mod, with_expr.where ());
186
- // Access in an array can appear as an index_exprt or a byte_extract
187
- auto index_reverted = expr_skeletont::clear_innermost_index_expr (
188
- assignment.original_lhs_skeleton );
189
- lhs_skeleton = index_reverted
190
- ? *index_reverted
191
- : get_value_or_abort (
192
- expr_skeletont::clear_innermost_byte_extract_expr (
193
- assignment.original_lhs_skeleton ));
194
- }
195
- else
196
- {
197
- field_sensitive_lhs = member_exprt (
198
- lhs_mod,
199
- with_expr.where ().get (ID_component_name),
200
- with_expr.new_value ().type ());
201
- lhs_skeleton =
202
- get_value_or_abort (expr_skeletont::clear_innermost_member_expr (
203
- assignment.original_lhs_skeleton ));
204
- }
205
-
206
- field_sensitive_lhs = state.field_sensitivity .apply (
207
- ns, state, std::move (field_sensitive_lhs), true );
208
-
209
- if (field_sensitive_lhs.id () != ID_symbol)
210
- break ;
211
-
212
- ssa_rhs = with_expr.new_value ();
213
- lhs_mod = to_ssa_expr (field_sensitive_lhs);
214
- assignment.original_lhs_skeleton = lhs_skeleton;
215
- }
216
- }
217
- return assignment;
218
- }
219
-
220
- // / Replace byte-update operations that only affect individual fields of an
221
- // / expression by assignments to just those fields. May generate "with" (or
222
- // / "update") expressions, which \ref rewrite_with_to_field_symbols will then
223
- // / take care of.
224
- // / \tparam use_update: use update_exprt instead of with_exprt when building
225
- // / expressions that modify components of an array or a struct
226
- // / \param [in, out] state: symbolic execution state to perform renaming
227
- // / \param assignment: assignment to transform
228
- // / \param ns: namespace
229
- // / \param do_simplify: set to true if, and only if, simplification is enabled
230
- // / \return updated assignment
231
- template <bool use_update>
232
- static assignmentt shift_indexed_access_to_lhs (
233
- goto_symext::statet &state,
234
- assignmentt assignment,
235
- const namespacet &ns,
236
- bool do_simplify)
237
- {
238
- exprt &ssa_rhs = assignment.rhs ;
239
- ssa_exprt &lhs_mod = assignment.lhs ;
240
- if (
241
- ssa_rhs.id () == ID_byte_update_little_endian ||
242
- ssa_rhs.id () == ID_byte_update_big_endian)
243
- {
244
- const byte_update_exprt &byte_update = to_byte_update_expr (ssa_rhs);
245
- exprt byte_extract = byte_extract_exprt (
246
- byte_update.id () == ID_byte_update_big_endian
247
- ? ID_byte_extract_big_endian
248
- : ID_byte_extract_little_endian,
249
- lhs_mod,
250
- byte_update.offset (),
251
- byte_update.value ().type ());
252
- if (do_simplify)
253
- simplify (byte_extract, ns);
254
-
255
- if (byte_extract.id () == ID_symbol)
256
- {
257
- return assignmentt{to_ssa_expr (byte_extract),
258
- std::move (assignment.original_lhs_skeleton ),
259
- byte_update.value ()};
260
- }
261
- else if (byte_extract.id () == ID_index || byte_extract.id () == ID_member)
262
- {
263
- ssa_rhs = byte_update.value ();
264
-
265
- while (byte_extract.id () == ID_index || byte_extract.id () == ID_member)
266
- {
267
- if (byte_extract.id () == ID_index)
268
- {
269
- index_exprt &idx = to_index_expr (byte_extract);
270
- ssa_rhs = [&]() -> exprt {
271
- if (use_update)
272
- {
273
- update_exprt new_rhs{idx.array (), exprt{}, ssa_rhs};
274
- new_rhs.designator ().push_back (index_designatort{idx.index ()});
275
- return std::move (new_rhs);
276
- }
277
- else
278
- return with_exprt{idx.array (), idx.index (), ssa_rhs};
279
- }();
280
- byte_extract = idx.array ();
281
- }
282
- else
283
- {
284
- member_exprt &member = to_member_expr (byte_extract);
285
- const irep_idt &component_name = member.get_component_name ();
286
- ssa_rhs = [&]() -> exprt {
287
- if (use_update)
288
- {
289
- update_exprt new_rhs{member.compound (), exprt{}, ssa_rhs};
290
- new_rhs.designator ().push_back (
291
- member_designatort{component_name});
292
- return std::move (new_rhs);
293
- }
294
- else
295
- {
296
- with_exprt new_rhs (
297
- member.compound (), exprt (ID_member_name), ssa_rhs);
298
- new_rhs.where ().set (ID_component_name, component_name);
299
- return std::move (new_rhs);
300
- }
301
- }();
302
- byte_extract = member.compound ();
303
- }
304
- }
305
-
306
- // We may have shifted the previous lhs into the rhs; as the lhs is only
307
- // L1-renamed, we need to rename again.
308
- return assignmentt{to_ssa_expr (byte_extract),
309
- std::move (assignment.original_lhs_skeleton ),
310
- state.rename (std::move (ssa_rhs), ns).get ()};
311
- }
312
- }
313
- return assignment;
314
- }
315
-
316
116
// / Assign a struct expression to a symbol. If \ref symex_assignt::assign_symbol
317
117
// / was used then we would assign the whole symbol, before extracting its
318
118
// / components, with results like
0 commit comments