@@ -113,206 +113,6 @@ struct assignmentt final
113113 exprt rhs;
114114};
115115
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-
316116// / Assign a struct expression to a symbol. If \ref symex_assignt::assign_symbol
317117// / was used then we would assign the whole symbol, before extracting its
318118// / components, with results like
0 commit comments