Skip to content

Commit ec90bba

Browse files
Merge pull request #4840 from romainbrenguier/clean-up/ifdef
Replace use of #ifdef by template parameter in symex_assign
2 parents af9ef78 + 43fffdf commit ec90bba

File tree

2 files changed

+154
-129
lines changed

2 files changed

+154
-129
lines changed

src/goto-symex/symex_assign.cpp

Lines changed: 148 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ Author: Daniel Kroening, [email protected]
2222
// update_exprt.
2323
// #define USE_UPDATE
2424

25+
constexpr bool use_update()
26+
{
27+
#ifdef USE_UPDATE
28+
return true;
29+
#else
30+
return false;
31+
#endif
32+
}
33+
2534
/// Store the \p what expression by recursively descending into the operands
2635
/// of \p lhs until the first operand \c op0 is _nil_: this _nil_ operand
2736
/// is then replaced with \p what.
@@ -71,12 +80,15 @@ void symex_assignt::assign_rec(
7180
assign_symbol(to_ssa_expr(lhs), full_lhs, rhs, guard);
7281
}
7382
else if(lhs.id() == ID_index)
74-
assign_array(to_index_expr(lhs), full_lhs, rhs, guard);
83+
assign_array<use_update()>(to_index_expr(lhs), full_lhs, rhs, guard);
7584
else if(lhs.id()==ID_member)
7685
{
7786
const typet &type = to_member_expr(lhs).struct_op().type();
7887
if(type.id() == ID_struct || type.id() == ID_struct_tag)
79-
assign_struct_member(to_member_expr(lhs), full_lhs, rhs, guard);
88+
{
89+
assign_struct_member<use_update()>(
90+
to_member_expr(lhs), full_lhs, rhs, guard);
91+
}
8092
else if(type.id() == ID_union || type.id() == ID_union_tag)
8193
{
8294
// should have been replaced by byte_extract
@@ -147,92 +159,102 @@ struct assignmentt final
147159
/// \ref symex_assignt::assign_struct_member have done, but now making use
148160
/// of the index/member that may only be known after renaming to L2 has taken
149161
/// place.
162+
/// \tparam use_update: use update_exprt instead of with_exprt when building
163+
/// expressions that modify components of an array or a struct
150164
/// \param [in, out] state: symbolic execution state to perform renaming
151165
/// \param assignment: an assignment to rewrite
152166
/// \param ns: namespace
153167
/// \return the updated assignment
168+
template <bool use_update>
154169
static assignmentt rewrite_with_to_field_symbols(
155170
goto_symext::statet &state,
156171
assignmentt assignment,
157172
const namespacet &ns)
158173
{
159174
exprt &ssa_rhs = assignment.rhs;
160175
ssa_exprt &lhs_mod = assignment.lhs;
161-
#ifdef USE_UPDATE
162-
while(ssa_rhs.id() == ID_update &&
163-
to_update_expr(ssa_rhs).designator().size() == 1 &&
164-
(lhs_mod.type().id() == ID_array || lhs_mod.type().id() == ID_struct ||
165-
lhs_mod.type().id() == ID_struct_tag))
176+
if(use_update)
166177
{
167-
exprt field_sensitive_lhs;
168-
const update_exprt &update = to_update_expr(ssa_rhs);
169-
PRECONDITION(update.designator().size() == 1);
170-
const exprt &designator = update.designator().front();
171-
172-
if(lhs_mod.type().id() == ID_array)
178+
while(ssa_rhs.id() == ID_update &&
179+
to_update_expr(ssa_rhs).designator().size() == 1 &&
180+
(lhs_mod.type().id() == ID_array ||
181+
lhs_mod.type().id() == ID_struct ||
182+
lhs_mod.type().id() == ID_struct_tag))
173183
{
174-
field_sensitive_lhs =
175-
index_exprt(lhs_mod, to_index_designator(designator).index());
176-
}
177-
else
178-
{
179-
field_sensitive_lhs = member_exprt(
180-
lhs_mod,
181-
to_member_designator(designator).get_component_name(),
182-
update.new_value().type());
183-
}
184+
exprt field_sensitive_lhs;
185+
const update_exprt &update = to_update_expr(ssa_rhs);
186+
PRECONDITION(update.designator().size() == 1);
187+
const exprt &designator = update.designator().front();
184188

185-
state.field_sensitivity.apply(state, field_sensitive_lhs, true);
189+
if(lhs_mod.type().id() == ID_array)
190+
{
191+
field_sensitive_lhs =
192+
index_exprt(lhs_mod, to_index_designator(designator).index());
193+
}
194+
else
195+
{
196+
field_sensitive_lhs = member_exprt(
197+
lhs_mod,
198+
to_member_designator(designator).get_component_name(),
199+
update.new_value().type());
200+
}
186201

187-
if(field_sensitive_lhs.id() != ID_symbol)
188-
break;
202+
state.field_sensitivity.apply(ns, state, field_sensitive_lhs, true);
189203

190-
ssa_rhs = update.new_value();
191-
lhs_mod = to_ssa_expr(field_sensitive_lhs);
192-
}
193-
#else
194-
while(ssa_rhs.id() == ID_with &&
195-
to_with_expr(ssa_rhs).operands().size() == 3 &&
196-
(lhs_mod.type().id() == ID_array || lhs_mod.type().id() == ID_struct ||
197-
lhs_mod.type().id() == ID_struct_tag))
198-
{
199-
exprt field_sensitive_lhs;
200-
const with_exprt &with_expr = to_with_expr(ssa_rhs);
204+
if(field_sensitive_lhs.id() != ID_symbol)
205+
break;
201206

202-
if(lhs_mod.type().id() == ID_array)
203-
{
204-
field_sensitive_lhs = index_exprt(lhs_mod, with_expr.where());
207+
ssa_rhs = update.new_value();
208+
lhs_mod = to_ssa_expr(field_sensitive_lhs);
205209
}
206-
else
210+
}
211+
else
212+
{
213+
while(
214+
ssa_rhs.id() == ID_with && to_with_expr(ssa_rhs).operands().size() == 3 &&
215+
(lhs_mod.type().id() == ID_array || lhs_mod.type().id() == ID_struct ||
216+
lhs_mod.type().id() == ID_struct_tag))
207217
{
208-
field_sensitive_lhs = member_exprt(
209-
lhs_mod,
210-
with_expr.where().get(ID_component_name),
211-
with_expr.new_value().type());
212-
}
218+
exprt field_sensitive_lhs;
219+
const with_exprt &with_expr = to_with_expr(ssa_rhs);
213220

214-
field_sensitive_lhs = state.field_sensitivity.apply(
215-
ns, state, std::move(field_sensitive_lhs), true);
221+
if(lhs_mod.type().id() == ID_array)
222+
{
223+
field_sensitive_lhs = index_exprt(lhs_mod, with_expr.where());
224+
}
225+
else
226+
{
227+
field_sensitive_lhs = member_exprt(
228+
lhs_mod,
229+
with_expr.where().get(ID_component_name),
230+
with_expr.new_value().type());
231+
}
216232

217-
if(field_sensitive_lhs.id() != ID_symbol)
218-
break;
233+
field_sensitive_lhs = state.field_sensitivity.apply(
234+
ns, state, std::move(field_sensitive_lhs), true);
219235

220-
ssa_rhs = with_expr.new_value();
221-
lhs_mod = to_ssa_expr(field_sensitive_lhs);
236+
if(field_sensitive_lhs.id() != ID_symbol)
237+
break;
238+
239+
ssa_rhs = with_expr.new_value();
240+
lhs_mod = to_ssa_expr(field_sensitive_lhs);
241+
}
222242
}
223-
#endif
224243
return assignment;
225244
}
226245

227246
/// Replace byte-update operations that only affect individual fields of an
228247
/// expression by assignments to just those fields. May generate "with" (or
229248
/// "update") expressions, which \ref rewrite_with_to_field_symbols will then
230249
/// take care of.
250+
/// \tparam use_update: use update_exprt instead of with_exprt when building
251+
/// expressions that modify components of an array or a struct
231252
/// \param [in, out] state: symbolic execution state to perform renaming
232253
/// \param assignment: assignment to transform
233254
/// \param ns: namespace
234255
/// \param do_simplify: set to true if, and only if, simplification is enabled
235256
/// \return updated assignment
257+
template <bool use_update>
236258
static assignmentt shift_indexed_access_to_lhs(
237259
goto_symext::statet &state,
238260
assignmentt assignment,
@@ -269,31 +291,38 @@ static assignmentt shift_indexed_access_to_lhs(
269291
if(byte_extract.id() == ID_index)
270292
{
271293
index_exprt &idx = to_index_expr(byte_extract);
272-
273-
#ifdef USE_UPDATE
274-
update_exprt new_rhs{idx.array(), exprt{}, ssa_rhs};
275-
new_rhs.designator().push_back(index_designatort{idx.index()});
276-
#else
277-
with_exprt new_rhs{idx.array(), idx.index(), ssa_rhs};
278-
#endif
279-
280-
ssa_rhs = new_rhs;
294+
ssa_rhs = [&]() -> exprt {
295+
if(use_update)
296+
{
297+
update_exprt new_rhs{idx.array(), exprt{}, ssa_rhs};
298+
new_rhs.designator().push_back(index_designatort{idx.index()});
299+
return std::move(new_rhs);
300+
}
301+
else
302+
return with_exprt{idx.array(), idx.index(), ssa_rhs};
303+
}();
281304
byte_extract = idx.array();
282305
}
283306
else
284307
{
285308
member_exprt &member = to_member_expr(byte_extract);
286309
const irep_idt &component_name = member.get_component_name();
287-
288-
#ifdef USE_UPDATE
289-
update_exprt new_rhs{member.compound(), exprt{}, ssa_rhs};
290-
new_rhs.designator().push_back(member_designatort{component_name});
291-
#else
292-
with_exprt new_rhs(member.compound(), exprt(ID_member_name), ssa_rhs);
293-
new_rhs.where().set(ID_component_name, component_name);
294-
#endif
295-
296-
ssa_rhs = new_rhs;
310+
ssa_rhs = [&]() -> exprt {
311+
if(use_update)
312+
{
313+
update_exprt new_rhs{member.compound(), exprt{}, ssa_rhs};
314+
new_rhs.designator().push_back(
315+
member_designatort{component_name});
316+
return std::move(new_rhs);
317+
}
318+
else
319+
{
320+
with_exprt new_rhs(
321+
member.compound(), exprt(ID_member_name), ssa_rhs);
322+
new_rhs.where().set(ID_component_name, component_name);
323+
return std::move(new_rhs);
324+
}
325+
}();
297326
byte_extract = member.compound();
298327
}
299328
}
@@ -361,9 +390,10 @@ void symex_assignt::assign_non_struct_symbol(
361390
// introduced by assign_struct_member, are transformed into member
362391
// expressions on the LHS. If we add an option to disable field-sensitivity
363392
// in the future these should be omitted.
364-
auto assignment = shift_indexed_access_to_lhs(
393+
auto assignment = shift_indexed_access_to_lhs<use_update()>(
365394
state, assignmentt{lhs, std::move(l2_rhs)}, ns, symex_config.simplify_opt);
366-
assignment = rewrite_with_to_field_symbols(state, std::move(assignment), ns);
395+
assignment = rewrite_with_to_field_symbols<use_update()>(
396+
state, std::move(assignment), ns);
367397

368398
if(symex_config.simplify_opt)
369399
assignment.rhs = simplify_expr(std::move(assignment.rhs), ns);
@@ -437,6 +467,7 @@ void symex_assignt::assign_typecast(
437467
assign_rec(lhs.op(), new_full_lhs, rhs_typecasted, guard);
438468
}
439469

470+
template <bool use_update>
440471
void symex_assignt::assign_array(
441472
const index_exprt &lhs,
442473
const exprt &full_lhs,
@@ -449,36 +480,29 @@ void symex_assignt::assign_array(
449480

450481
PRECONDITION(lhs_index_type.id() == ID_array);
451482

452-
#ifdef USE_UPDATE
453-
454-
// turn
455-
// a[i]=e
456-
// into
457-
// a'==UPDATE(a, [i], e)
458-
459-
update_exprt new_rhs(lhs_index_type);
460-
new_rhs.old()=lhs_array;
461-
new_rhs.designator().push_back(index_designatort(lhs_index));
462-
new_rhs.new_value()=rhs;
463-
464-
exprt new_full_lhs=add_to_lhs(full_lhs, lhs);
465-
466-
symex_assign_rec(
467-
state, lhs_array, new_full_lhs, new_rhs, guard, assignment_type);
468-
469-
#else
470-
// turn
471-
// a[i]=e
472-
// into
473-
// a'==a WITH [i:=e]
474-
475-
const with_exprt new_rhs{lhs_array, lhs_index, rhs};
476-
const exprt new_full_lhs = add_to_lhs(full_lhs, lhs);
477-
478-
assign_rec(lhs_array, new_full_lhs, new_rhs, guard);
479-
#endif
483+
if(use_update)
484+
{
485+
// turn
486+
// a[i]=e
487+
// into
488+
// a'==UPDATE(a, [i], e)
489+
const update_exprt new_rhs{lhs_array, index_designatort(lhs_index), rhs};
490+
const exprt new_full_lhs = add_to_lhs(full_lhs, lhs);
491+
assign_rec(lhs_array, new_full_lhs, new_rhs, guard);
492+
}
493+
else
494+
{
495+
// turn
496+
// a[i]=e
497+
// into
498+
// a'==a WITH [i:=e]
499+
const with_exprt new_rhs{lhs_array, lhs_index, rhs};
500+
const exprt new_full_lhs = add_to_lhs(full_lhs, lhs);
501+
assign_rec(lhs_array, new_full_lhs, new_rhs, guard);
502+
}
480503
}
481504

505+
template <bool use_update>
482506
void symex_assignt::assign_struct_member(
483507
const member_exprt &lhs,
484508
const exprt &full_lhs,
@@ -514,35 +538,30 @@ void symex_assignt::assign_struct_member(
514538

515539
const irep_idt &component_name=lhs.get_component_name();
516540

517-
#ifdef USE_UPDATE
518-
519-
// turn
520-
// a.c=e
521-
// into
522-
// a'==UPDATE(a, .c, e)
523-
524-
update_exprt new_rhs(lhs_struct.type());
525-
new_rhs.old()=lhs_struct;
526-
new_rhs.designator().push_back(member_designatort(component_name));
527-
new_rhs.new_value()=rhs;
528-
529-
exprt new_full_lhs=add_to_lhs(full_lhs, lhs);
530-
531-
symex_assign_rec(
532-
state, lhs_struct, new_full_lhs, new_rhs, guard, assignment_type);
533-
534-
#else
535-
// turn
536-
// a.c=e
537-
// into
538-
// a'==a WITH [c:=e]
541+
if(use_update)
542+
{
543+
// turn
544+
// a.c=e
545+
// into
546+
// a'==UPDATE(a, .c, e)
547+
const update_exprt new_rhs{
548+
lhs_struct, member_designatort(component_name), rhs};
549+
const exprt new_full_lhs = add_to_lhs(full_lhs, lhs);
550+
assign_rec(lhs_struct, new_full_lhs, new_rhs, guard);
551+
}
552+
else
553+
{
554+
// turn
555+
// a.c=e
556+
// into
557+
// a'==a WITH [c:=e]
539558

540-
with_exprt new_rhs(lhs_struct, exprt(ID_member_name), rhs);
541-
new_rhs.where().set(ID_component_name, component_name);
559+
with_exprt new_rhs(lhs_struct, exprt(ID_member_name), rhs);
560+
new_rhs.where().set(ID_component_name, component_name);
542561

543-
exprt new_full_lhs=add_to_lhs(full_lhs, lhs);
544-
assign_rec(lhs_struct, new_full_lhs, new_rhs, guard);
545-
#endif
562+
exprt new_full_lhs = add_to_lhs(full_lhs, lhs);
563+
assign_rec(lhs_struct, new_full_lhs, new_rhs, guard);
564+
}
546565
}
547566

548567
void symex_assignt::assign_if(

0 commit comments

Comments
 (0)