Skip to content

Commit fc1df25

Browse files
authored
Merge pull request #4309 from smowton/smowton/cleanup/regularise-symex-dispatch
Regularise the style and division of responsibilities in symex dispatch
2 parents b4f65c8 + cca1dca commit fc1df25

File tree

5 files changed

+67
-63
lines changed

5 files changed

+67
-63
lines changed

src/goto-symex/goto_symex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,14 @@ class goto_symext
223223
virtual void symex_dead(statet &);
224224
virtual void symex_other(statet &);
225225

226+
void symex_assert(const goto_programt::instructiont &, statet &);
226227
virtual void vcc(
227228
const exprt &,
228229
const std::string &msg,
229230
statet &);
230231

231232
virtual void symex_assume(statet &, const exprt &cond);
233+
void symex_assume_l2(statet &, const exprt &cond);
232234

233235
/// Merge all branches joining at the current program point. Applies
234236
/// \ref merge_goto for each goto state (each of which corresponds to previous

src/goto-symex/symex_function_call.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,18 @@ void goto_symext::symex_function_call(
194194
void goto_symext::symex_function_call_symbol(
195195
const get_goto_functiont &get_goto_function,
196196
statet &state,
197-
const code_function_callt &code)
197+
const code_function_callt &original_code)
198198
{
199+
code_function_callt code = original_code;
200+
201+
if(code.lhs().is_not_nil())
202+
clean_expr(code.lhs(), state, true);
203+
204+
clean_expr(code.function(), state, false);
205+
206+
Forall_expr(it, code.arguments())
207+
clean_expr(*it, state, false);
208+
199209
target.location(state.guard.as_expr(), state.source);
200210

201211
PRECONDITION(code.function().id() == ID_symbol);
@@ -437,4 +447,3 @@ static void locality(
437447
state.l1_history.insert(l1_name);
438448
}
439449
}
440-

src/goto-symex/symex_goto.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ void goto_symext::symex_goto(statet &state)
2727
const goto_programt::instructiont &instruction=*state.source.pc;
2828
framet &frame = state.top();
2929

30-
if(state.guard.is_false())
31-
{
32-
// next instruction
33-
symex_transition(state);
34-
return; // nothing to do
35-
}
36-
3730
exprt new_guard = instruction.get_condition();
3831
clean_expr(new_guard, state, false);
3932

@@ -75,9 +68,9 @@ void goto_symext::symex_goto(statet &state)
7568
// generate assume(false) or a suitable negation if this
7669
// instruction is a conditional goto
7770
if(new_guard.is_true())
78-
symex_assume(state, false_exprt());
71+
symex_assume_l2(state, false_exprt());
7972
else
80-
symex_assume(state, not_exprt(new_guard));
73+
symex_assume_l2(state, not_exprt(new_guard));
8174

8275
// next instruction
8376
symex_transition(state);
@@ -552,17 +545,18 @@ void goto_symext::loop_bound_exceeded(
552545
if(symex_config.unwinding_assertions)
553546
{
554547
// Generate VCC for unwinding assertion.
555-
vcc(negated_cond,
556-
"unwinding assertion loop "+std::to_string(loop_number),
557-
state);
548+
vcc(
549+
negated_cond,
550+
"unwinding assertion loop " + std::to_string(loop_number),
551+
state);
558552

559553
// add to state guard to prevent further assignments
560554
state.guard.add(negated_cond);
561555
}
562556
else
563557
{
564558
// generate unwinding assumption, unless we permit partial loops
565-
symex_assume(state, negated_cond);
559+
symex_assume_l2(state, negated_cond);
566560
}
567561
}
568562
}

src/goto-symex/symex_main.cpp

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -76,51 +76,71 @@ void symex_transition(goto_symext::statet &state)
7676
symex_transition(state, next, false);
7777
}
7878

79-
void goto_symext::vcc(
80-
const exprt &vcc_expr,
81-
const std::string &msg,
79+
void goto_symext::symex_assert(
80+
const goto_programt::instructiont &instruction,
8281
statet &state)
8382
{
84-
state.total_vccs++;
85-
path_segment_vccs++;
86-
87-
exprt expr=vcc_expr;
83+
exprt condition = instruction.get_condition();
84+
clean_expr(condition, state, false);
8885

8986
// we are willing to re-write some quantified expressions
90-
if(has_subexpr(expr, ID_exists) || has_subexpr(expr, ID_forall))
87+
if(has_subexpr(condition, ID_exists) || has_subexpr(condition, ID_forall))
9188
{
9289
// have negation pushed inwards as far as possible
93-
do_simplify(expr);
94-
rewrite_quantifiers(expr, state);
90+
do_simplify(condition);
91+
rewrite_quantifiers(condition, state);
9592
}
9693

9794
// now rename, enables propagation
98-
exprt l2_expr = state.rename(std::move(expr), ns);
95+
exprt l2_condition = state.rename(std::move(condition), ns);
9996

10097
// now try simplifier on it
101-
do_simplify(l2_expr);
98+
do_simplify(l2_condition);
10299

103-
if(l2_expr.is_true())
100+
std::string msg = id2string(instruction.source_location.get_comment());
101+
if(msg == "")
102+
msg = "assertion";
103+
104+
vcc(l2_condition, msg, state);
105+
}
106+
107+
void goto_symext::vcc(
108+
const exprt &condition,
109+
const std::string &msg,
110+
statet &state)
111+
{
112+
state.total_vccs++;
113+
path_segment_vccs++;
114+
115+
if(condition.is_true())
104116
return;
105117

106-
state.guard.guard_expr(l2_expr);
118+
exprt guarded_condition = condition;
119+
state.guard.guard_expr(guarded_condition);
107120

108121
state.remaining_vccs++;
109-
target.assertion(state.guard.as_expr(), l2_expr, msg, state.source);
122+
target.assertion(state.guard.as_expr(), guarded_condition, msg, state.source);
110123
}
111124

112125
void goto_symext::symex_assume(statet &state, const exprt &cond)
113126
{
114127
exprt simplified_cond=cond;
115128

129+
clean_expr(simplified_cond, state, false);
130+
simplified_cond = state.rename(std::move(simplified_cond), ns);
116131
do_simplify(simplified_cond);
117132

118-
if(simplified_cond.is_true())
133+
symex_assume_l2(state, simplified_cond);
134+
}
135+
136+
void goto_symext::symex_assume_l2(statet &state, const exprt &cond)
137+
{
138+
if(cond.is_true())
119139
return;
120140

121141
if(state.threads.size()==1)
122142
{
123-
exprt tmp=simplified_cond;
143+
exprt tmp = cond;
124144
state.guard.guard_expr(tmp);
125145
target.assumption(state.guard.as_expr(), tmp, state.source);
126146
}
@@ -131,7 +151,7 @@ void goto_symext::symex_assume(statet &state, const exprt &cond)
131151
// x=0; assume(x==1);
132152
// assert(x!=42); x=42;
133153
else
134-
state.guard.add(simplified_cond);
154+
state.guard.add(cond);
135155

136156
if(state.atomic_section_id!=0 &&
137157
state.guard.is_false())
@@ -402,31 +422,21 @@ void goto_symext::symex_step(
402422
break;
403423

404424
case GOTO:
405-
symex_goto(state);
425+
if(!state.guard.is_false())
426+
symex_goto(state);
427+
else
428+
symex_transition(state);
406429
break;
407430

408431
case ASSUME:
409432
if(!state.guard.is_false())
410-
{
411-
exprt tmp = instruction.get_condition();
412-
clean_expr(tmp, state, false);
413-
symex_assume(state, state.rename(std::move(tmp), ns));
414-
}
415-
433+
symex_assume(state, instruction.get_condition());
416434
symex_transition(state);
417435
break;
418436

419437
case ASSERT:
420438
if(!state.guard.is_false())
421-
{
422-
std::string msg=id2string(state.source.pc->source_location.get_comment());
423-
if(msg=="")
424-
msg="assertion";
425-
exprt tmp(instruction.get_condition());
426-
clean_expr(tmp, state, false);
427-
vcc(tmp, msg, state);
428-
}
429-
439+
symex_assert(instruction, state);
430440
symex_transition(state);
431441
break;
432442

@@ -445,17 +455,8 @@ void goto_symext::symex_step(
445455
case FUNCTION_CALL:
446456
if(!state.guard.is_false())
447457
{
448-
code_function_callt deref_code = instruction.get_function_call();
449-
450-
if(deref_code.lhs().is_not_nil())
451-
clean_expr(deref_code.lhs(), state, true);
452-
453-
clean_expr(deref_code.function(), state, false);
454-
455-
Forall_expr(it, deref_code.arguments())
456-
clean_expr(*it, state, false);
457-
458-
symex_function_call(get_goto_function, state, deref_code);
458+
symex_function_call(
459+
get_goto_function, state, instruction.get_function_call());
459460
}
460461
else
461462
symex_transition(state);
@@ -464,14 +465,12 @@ void goto_symext::symex_step(
464465
case OTHER:
465466
if(!state.guard.is_false())
466467
symex_other(state);
467-
468468
symex_transition(state);
469469
break;
470470

471471
case DECL:
472472
if(!state.guard.is_false())
473473
symex_decl(state);
474-
475474
symex_transition(state);
476475
break;
477476

src/goto-symex/symex_throw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ void goto_symext::symex_throw(statet &state)
4949
#endif
5050

5151
// An un-caught exception. Behaves like assume(0);
52-
symex_assume(state, false_exprt());
52+
symex_assume_l2(state, false_exprt());
5353
}

0 commit comments

Comments
 (0)