Skip to content

Commit 192d01e

Browse files
level2t type for results of rename_level2
Makes it clear from the type that rename_level2 rename an expression up to level2, and allows us to the renaming level in the type. The argument is now passed by copy and a new expression is returned, which also makes the interface of the function clearer. Note that because of that we need a new version of rename_level2 returning a level2t<ssa_exprt>: before, an ssa_exprt was given as argument and the type left unchanged but new the argument is copied, so the returned type would only be level2t<exprt>.
1 parent 949337a commit 192d01e

10 files changed

+106
-85
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ bool scratch_programt::check_sat(bool do_slice)
6262

6363
exprt scratch_programt::eval(const exprt &e)
6464
{
65-
return checker->get(symex_state.rename_level2(e, ns));
65+
return checker->get(symex_state.rename_level2(e, ns).expr);
6666
}
6767

6868
void scratch_programt::append(goto_programt::instructionst &new_instructions)

src/goto-symex/goto_symex_state.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ goto_symex_statet::rename_level1(exprt expr, const namespacet &ns)
389389
}
390390
}
391391

392-
ssa_exprt
392+
level2t<ssa_exprt>
393393
goto_symex_statet::rename_level2_ssa(ssa_exprt ssa, const namespacet &ns)
394394
{
395395
set_l1_indices(level0, level1, ssa, source.thread_nr, ns);
@@ -415,10 +415,11 @@ goto_symex_statet::rename_level2_ssa(ssa_exprt ssa, const namespacet &ns)
415415
else
416416
set_l2_indices(level0, level1, level2, ssa, source.thread_nr, ns);
417417
}
418-
return ssa;
418+
return level2t<ssa_exprt>{ssa};
419419
}
420420

421-
exprt goto_symex_statet::rename_level2(exprt expr, const namespacet &ns)
421+
level2t<exprt>
422+
goto_symex_statet::rename_level2(exprt expr, const namespacet &ns)
422423
{
423424
// rename all the symbols with their last known value
424425
if(expr.id()==ID_symbol &&
@@ -474,7 +475,7 @@ exprt goto_symex_statet::rename_level2(exprt expr, const namespacet &ns)
474475

475476
// do this recursively
476477
Forall_operands(it, expr)
477-
*it = rename_level2(std::move(*it), ns);
478+
*it = rename_level2(std::move(*it), ns).expr;
478479

479480
// some fixes
480481
if(expr.id()==ID_with)
@@ -489,7 +490,7 @@ exprt goto_symex_statet::rename_level2(exprt expr, const namespacet &ns)
489490
expr.type()=to_if_expr(expr).true_case().type();
490491
}
491492
}
492-
return expr;
493+
return level2t<exprt>{expr};
493494
}
494495

495496
/// thread encoding
@@ -780,7 +781,7 @@ void goto_symex_statet::rename(
780781
if(level == L1)
781782
e = rename_level1(e, ns).expr;
782783
else
783-
rename_level2(e, ns);
784+
e = rename_level2(e, ns).expr;
784785
};
785786

786787
// rename all the symbols with their last known value

src/goto-symex/goto_symex_state.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ class goto_symex_statet final
7777
level1t<exprt> rename_level1(exprt expr, const namespacet &ns);
7878
level1t<ssa_exprt>
7979
rename_level1(level0t<ssa_exprt> l0_expr, const namespacet &ns);
80-
void rename_level2(exprt &expr, const namespacet &ns);
80+
level2t<exprt> rename_level2(exprt expr, const namespacet &ns);
81+
level2t<ssa_exprt> rename_level2(ssa_exprt ssa, const namespacet &ns);
8182
void rename(
8283
typet &type,
8384
const irep_idt &l1_identifier,

src/goto-symex/renaming_level.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ struct level1t
7171
underlyingt expr;
7272
};
7373

74+
/// Wrapper for expressions that have been renamed at level2
75+
template <typename underlyingt>
76+
struct level2t
77+
{
78+
static_assert(
79+
std::is_base_of<exprt, underlyingt>::value,
80+
"underlyingt should inherit from exprt");
81+
underlyingt expr;
82+
};
83+
7484
inline level1t<ssa_exprt> remove_level2(ssa_exprt ssa)
7585
{
7686
ssa.remove_level_2();

src/goto-symex/symex_assign.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,13 @@ void goto_symext::symex_assign_symbol(
212212
tmp_ssa_rhs.swap(ssa_rhs);
213213
}
214214

215-
exprt l2_rhs = state.rename_level2(std::move(ssa_rhs), ns);
216-
do_simplify(l2_rhs);
215+
level2t<exprt> l2_rhs = state.rename_level2(ssa_rhs, ns);
216+
do_simplify(l2_rhs.expr);
217217

218218
ssa_exprt ssa_lhs=lhs;
219219
state.assignment(
220220
ssa_lhs,
221-
l2_rhs,
221+
l2_rhs.expr,
222222
ns,
223223
symex_config.simplify_opt,
224224
symex_config.constant_propagation,
@@ -228,7 +228,7 @@ void goto_symext::symex_assign_symbol(
228228
ssa_full_lhs=add_to_lhs(ssa_full_lhs, ssa_lhs);
229229
const bool record_events=state.record_events;
230230
state.record_events=false;
231-
exprt l2_full_lhs = state.rename_level2(std::move(ssa_full_lhs), ns);
231+
level2t<exprt> l2_full_lhs = state.rename_level2(ssa_full_lhs, ns);
232232
state.record_events=record_events;
233233

234234
guardt tmp_guard(state.guard);
@@ -254,8 +254,9 @@ void goto_symext::symex_assign_symbol(
254254
target.assignment(
255255
tmp_guard.as_expr(),
256256
ssa_lhs,
257-
l2_full_lhs, add_to_lhs(full_lhs, ssa_lhs.get_original_expr()),
258-
ssa_rhs,
257+
l2_full_lhs.expr,
258+
add_to_lhs(full_lhs, ssa_lhs.get_original_expr()),
259+
l2_rhs.expr,
259260
state.source,
260261
assignment_type);
261262
}
@@ -407,20 +408,20 @@ void goto_symext::symex_assign_if(
407408

408409
guardt old_guard=guard;
409410

410-
exprt renamed_guard = state.rename_level2(lhs.cond(), ns);
411-
do_simplify(renamed_guard);
411+
level2t<exprt> renamed_guard = state.rename_level2(lhs.cond(), ns);
412+
do_simplify(renamed_guard.expr);
412413

413-
if(!renamed_guard.is_false())
414+
if(!renamed_guard.expr.is_false())
414415
{
415-
guard.add(renamed_guard);
416+
guard.add(renamed_guard.expr);
416417
symex_assign_rec(
417418
state, lhs.true_case(), full_lhs, rhs, guard, assignment_type);
418419
guard = std::move(old_guard);
419420
}
420421

421-
if(!renamed_guard.is_true())
422+
if(!renamed_guard.expr.is_true())
422423
{
423-
guard.add(not_exprt(renamed_guard));
424+
guard.add(not_exprt(renamed_guard.expr));
424425
symex_assign_rec(
425426
state, lhs.false_case(), full_lhs, rhs, guard, assignment_type);
426427
guard = std::move(old_guard);

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -70,36 +70,36 @@ void goto_symext::symex_allocate(
7070
else
7171
{
7272
// to allow constant propagation
73-
exprt tmp_size = state.rename_level2(size, ns);
74-
simplify(tmp_size, ns);
73+
level2t<exprt> tmp_size = state.rename_level2(size, ns);
74+
simplify(tmp_size.expr, ns);
7575

7676
// special treatment for sizeof(T)*x
7777
{
78-
const auto tmp_type = c_sizeof_type_rec(tmp_size);
78+
const auto tmp_type = c_sizeof_type_rec(tmp_size.expr);
7979

8080
if(tmp_type.has_value())
8181
{
8282
// Did the size get multiplied?
8383
auto elem_size = pointer_offset_size(*tmp_type, ns);
84-
const auto alloc_size = numeric_cast<mp_integer>(tmp_size);
84+
const auto alloc_size = numeric_cast<mp_integer>(tmp_size.expr);
8585

8686
if(!elem_size.has_value() || *elem_size==0)
8787
{
8888
}
8989
else if(
90-
!alloc_size.has_value() && tmp_size.id() == ID_mult &&
91-
tmp_size.operands().size() == 2 &&
92-
(tmp_size.op0().is_constant() ||
93-
tmp_size.op1().is_constant()))
90+
!alloc_size.has_value() && tmp_size.expr.id() == ID_mult &&
91+
tmp_size.expr.operands().size() == 2 &&
92+
(tmp_size.expr.op0().is_constant() ||
93+
tmp_size.expr.op1().is_constant()))
9494
{
95-
exprt s = tmp_size.op0();
95+
exprt s = tmp_size.expr.op0();
9696
if(s.is_constant())
9797
{
98-
s = tmp_size.op1();
99-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op0()) == *tmp_type);
98+
s = tmp_size.expr.op1();
99+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op0()) == *tmp_type);
100100
}
101101
else
102-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op1()) == *tmp_type);
102+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op1()) == *tmp_type);
103103

104104
object_type = array_typet(*tmp_type, s);
105105
}
@@ -112,15 +112,15 @@ void goto_symext::symex_allocate(
112112
mp_integer elements = *alloc_size / (*elem_size);
113113

114114
if(elements * (*elem_size) == *alloc_size)
115-
object_type =
116-
array_typet(*tmp_type, from_integer(elements, tmp_size.type()));
115+
object_type = array_typet(
116+
*tmp_type, from_integer(elements, tmp_size.expr.type()));
117117
}
118118
}
119119
}
120120
}
121121

122122
if(!object_type.has_value())
123-
object_type=array_typet(unsigned_char_type(), tmp_size);
123+
object_type = array_typet(unsigned_char_type(), tmp_size.expr);
124124

125125
// we introduce a fresh symbol for the size
126126
// to prevent any issues of the size getting ever changed
@@ -136,7 +136,7 @@ void goto_symext::symex_allocate(
136136
size_symbol.base_name=
137137
"dynamic_object_size"+std::to_string(dynamic_counter);
138138
size_symbol.name="symex_dynamic::"+id2string(size_symbol.base_name);
139-
size_symbol.type = tmp_size.type();
139+
size_symbol.type = tmp_size.expr.type();
140140
size_symbol.mode = mode;
141141
size_symbol.type.set(ID_C_constant, true);
142142
size_symbol.value = array_size;
@@ -163,14 +163,14 @@ void goto_symext::symex_allocate(
163163
state.symbol_table.add(value_symbol);
164164

165165
// to allow constant propagation
166-
exprt zero_init = state.rename_level2(code.op1(), ns);
167-
simplify(zero_init, ns);
166+
level2t<exprt> zero_init = state.rename_level2(code.op1(), ns);
167+
simplify(zero_init.expr, ns);
168168

169169
INVARIANT(
170-
zero_init.is_constant(),
170+
zero_init.expr.is_constant(),
171171
"allocate expects constant as second argument");
172172

173-
if(!zero_init.is_zero() && !zero_init.is_false())
173+
if(!zero_init.expr.is_zero() && !zero_init.expr.is_false())
174174
{
175175
const auto zero_value =
176176
zero_initializer(*object_type, code.source_location(), ns);
@@ -234,9 +234,9 @@ void goto_symext::symex_gcc_builtin_va_arg_next(
234234
return; // ignore
235235

236236
// to allow constant propagation
237-
exprt tmp = state.rename_level2(code.op0(), ns);
238-
do_simplify(tmp);
239-
irep_idt id = get_symbol(tmp);
237+
level2t<exprt> tmp = state.rename_level2(code.op0(), ns);
238+
do_simplify(tmp.expr);
239+
irep_idt id = get_symbol(tmp.expr);
240240

241241
const auto zero = zero_initializer(lhs.type(), code.source_location(), ns);
242242
CHECK_RETURN(zero.has_value());
@@ -311,10 +311,10 @@ void goto_symext::symex_printf(
311311
{
312312
PRECONDITION(!rhs.operands().empty());
313313

314-
exprt tmp_rhs = state.rename_level2(rhs, ns);
315-
do_simplify(tmp_rhs);
314+
level2t<exprt> tmp_rhs = state.rename_level2(rhs, ns);
315+
do_simplify(tmp_rhs.expr);
316316

317-
const exprt::operandst &operands = tmp_rhs.operands();
317+
const exprt::operandst &operands = tmp_rhs.expr.operands();
318318
std::list<exprt> args;
319319

320320
for(std::size_t i=1; i<operands.size(); i++)
@@ -335,19 +335,19 @@ void goto_symext::symex_input(
335335
{
336336
PRECONDITION(code.operands().size() >= 2);
337337

338-
exprt id_arg = state.rename_level2(code.op0(), ns);
338+
level2t<exprt> id_arg = state.rename_level2(code.op0(), ns);
339339

340340
std::list<exprt> args;
341341

342342
for(std::size_t i=1; i<code.operands().size(); i++)
343343
{
344344
args.push_back(code.operands()[i]);
345-
exprt l2_arg = state.rename_level2(args.back(), ns);
346-
do_simplify(l2_arg);
347-
args.back() = std::move(l2_arg);
345+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
346+
do_simplify(l2_arg.expr);
347+
args.back() = std::move(l2_arg.expr);
348348
}
349349

350-
const irep_idt input_id = get_string_argument(id_arg, ns);
350+
const irep_idt input_id = get_string_argument(id_arg.expr, ns);
351351

352352
target.input(state.guard.as_expr(), state.source, input_id, args);
353353
}
@@ -357,19 +357,19 @@ void goto_symext::symex_output(
357357
const codet &code)
358358
{
359359
PRECONDITION(code.operands().size() >= 2);
360-
exprt id_arg = state.rename_level2(code.op0(), ns);
360+
level2t<exprt> id_arg = state.rename_level2(code.op0(), ns);
361361

362362
std::list<exprt> args;
363363

364364
for(std::size_t i=1; i<code.operands().size(); i++)
365365
{
366366
args.push_back(code.operands()[i]);
367-
exprt l2_arg = state.rename_level2(args.back(), ns);
368-
do_simplify(l2_arg);
369-
args.back() = std::move(l2_arg);
367+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
368+
do_simplify(l2_arg.expr);
369+
args.back() = std::move(l2_arg.expr);
370370
}
371371

372-
const irep_idt output_id=get_string_argument(id_arg, ns);
372+
const irep_idt output_id = get_string_argument(id_arg.expr, ns);
373373

374374
target.output(state.guard.as_expr(), state.source, output_id, args);
375375
}
@@ -477,7 +477,7 @@ void goto_symext::symex_trace(
477477
irep_idt event = to_string_constant(code.arguments()[1].op0()).get_value();
478478

479479
for(std::size_t j=2; j<code.arguments().size(); j++)
480-
vars.push_back(state.rename_level2(code.arguments()[j], ns));
480+
vars.push_back(state.rename_level2(code.arguments()[j], ns).expr);
481481

482482
target.output(state.guard.as_expr(), state.source, event, vars);
483483
}

src/goto-symex/symex_decl.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
6969
symex_renaming_levelt::increase_counter(level2_it);
7070
const bool record_events=state.record_events;
7171
state.record_events=false;
72-
state.rename_level2(ssa.expr, ns);
72+
level2t<ssa_exprt> l2_expr = state.rename_level2(ssa.expr, ns);
7373
state.record_events=record_events;
7474

7575
// we hide the declaration of auxiliary variables
@@ -81,12 +81,17 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
8181

8282
target.decl(
8383
state.guard.as_expr(),
84-
ssa.expr,
84+
l2_expr.expr,
8585
state.source,
8686
hidden ? symex_targett::assignment_typet::HIDDEN
8787
: symex_targett::assignment_typet::STATE);
8888

89-
if(state.dirty(ssa.expr.get_object_name()) && state.atomic_section_id == 0)
89+
if(
90+
state.dirty(l2_expr.expr.get_object_name()) && state.atomic_section_id == 0)
91+
// TODO: make shared write take a level2 exprt
9092
target.shared_write(
91-
state.guard.as_expr(), ssa.expr, state.atomic_section_id, state.source);
93+
state.guard.as_expr(),
94+
l2_expr.expr,
95+
state.atomic_section_id,
96+
state.source);
9297
}

src/goto-symex/symex_function_call.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ void goto_symext::symex_function_call_code(
267267
// read the arguments -- before the locality renaming
268268
exprt::operandst arguments = call.arguments();
269269
for(auto &a : arguments)
270-
a = state.rename_level2(std::move(a), ns);
270+
a = state.rename_level2(std::move(a), ns).expr;
271271

272272
// we hide the call if the caller and callee are both hidden
273273
const bool hidden = state.top().hidden_function && goto_function.is_hidden();

0 commit comments

Comments
 (0)