Skip to content

Commit e3ff246

Browse files
authored
Merge pull request #3890 from diffblue/source-is-not-optional
symex: source is not optional
2 parents 3f0f776 + 9e0c5a3 commit e3ff246

10 files changed

+71
-105
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ bool scratch_programt::check_sat(bool do_slice)
3535
output(ns, "scratch", std::cout);
3636
#endif
3737

38+
symex_state = util_make_unique<goto_symex_statet>(
39+
symex_targett::sourcet(goto_functionst::entry_point(), *this));
3840
symex.symex_with_state(
39-
symex_state,
41+
*symex_state,
4042
[this](const irep_idt &key) -> const goto_functionst::goto_functiont & {
4143
return functions.function_map.at(key);
4244
},
@@ -69,7 +71,7 @@ exprt scratch_programt::eval(const exprt &e)
6971
{
7072
exprt ssa=e;
7173

72-
symex_state.rename(ssa, ns);
74+
symex_state->rename(ssa, ns);
7375

7476
return checker->get(ssa);
7577
}

src/goto-instrument/accelerate/scratch_program.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class scratch_programt:public goto_programt
7474
bool constant_propagation;
7575

7676
protected:
77-
goto_symex_statet symex_state;
77+
std::unique_ptr<goto_symex_statet> symex_state;
7878
goto_functionst functions;
7979
symbol_tablet &symbol_table;
8080
symbol_tablet symex_symbol_table;

src/goto-symex/goto_symex.h

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -149,28 +149,12 @@ class goto_symext
149149
protected:
150150
const symex_configt symex_config;
151151

152-
/// Initialise the symbolic execution and the given state with <code>pc</code>
153-
/// as entry point.
154-
/// \param state: Symex state to initialise.
155-
/// \param get_goto_function: producer for GOTO functions
156-
/// \param function_identifier: The function in which the instructions are
157-
/// \param pc: first instruction to symex
158-
/// \param limit: final instruction, which itself will not
159-
/// be symexed.
160-
void initialize_entry_point(
161-
statet &state,
162-
const get_goto_functiont &get_goto_function,
163-
const irep_idt &function_identifier,
164-
goto_programt::const_targett pc,
165-
goto_programt::const_targett limit);
166-
167152
/// Initialize the symbolic execution and the given state with
168153
/// the beginning of the entry point function.
169154
/// \param get_goto_function: producer for GOTO functions
170-
/// \param state: Symex state to initialize.
171-
void initialize_entry_point_state(
172-
const get_goto_functiont &get_goto_function,
173-
statet &state);
155+
/// \return Initialized symex state.
156+
std::unique_ptr<statet>
157+
initialize_entry_point_state(const get_goto_functiont &get_goto_function);
174158

175159
/// Invokes symex_step and verifies whether additional threads can be
176160
/// executed.

src/goto-symex/goto_symex_state.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ Author: Daniel Kroening, [email protected]
2727

2828
static void get_l1_name(exprt &expr);
2929

30-
goto_symex_statet::goto_symex_statet()
31-
: symex_target(nullptr), record_events(true), dirty()
30+
goto_symex_statet::goto_symex_statet(const symex_targett::sourcet &_source)
31+
: goto_statet(_source), symex_target(nullptr), record_events(true), dirty()
3232
{
3333
threads.resize(1);
3434
new_frame();
@@ -782,11 +782,8 @@ void goto_symex_statet::print_backtrace(std::ostream &out) const
782782
++stackit)
783783
{
784784
const auto &frame = *stackit;
785-
if(frame.calling_location.is_set)
786-
{
787-
out << frame.calling_location.function_id << " "
788-
<< frame.calling_location.pc->location_number << "\n";
789-
}
785+
out << frame.calling_location.function_id << " "
786+
<< frame.calling_location.pc->location_number << "\n";
790787
}
791788
}
792789

src/goto-symex/goto_symex_state.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ class goto_statet
7272
unsigned total_vccs = 0;
7373
unsigned remaining_vccs = 0;
7474

75+
/// Constructors
7576
explicit goto_statet(const class goto_symex_statet &s);
76-
goto_statet() = default;
77+
explicit goto_statet(const symex_targett::sourcet &_source) : source(_source)
78+
{
79+
}
7780
};
7881

7982
// stack frames -- these are used for function calls and
@@ -124,7 +127,7 @@ struct framet
124127
class goto_symex_statet final : public goto_statet
125128
{
126129
public:
127-
goto_symex_statet();
130+
explicit goto_symex_statet(const symex_targett::sourcet &);
128131
~goto_symex_statet();
129132

130133
/// \brief Fake "copy constructor" that initializes the `symex_target` member

src/goto-symex/symex_function_call.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ void goto_symext::symex_function_call_code(
326326
frame.loop_iterations[identifier].is_recursion=true;
327327
frame.loop_iterations[identifier].count++;
328328

329-
state.source.is_set=true;
330329
state.source.function_id = identifier;
331330
symex_transition(state, goto_function.body.instructions.begin(), false);
332331
}

src/goto-symex/symex_main.cpp

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -159,34 +159,6 @@ void goto_symext::rewrite_quantifiers(exprt &expr, statet &state)
159159
}
160160
}
161161

162-
void goto_symext::initialize_entry_point(
163-
statet &state,
164-
const get_goto_functiont &get_goto_function,
165-
const irep_idt &function_id,
166-
const goto_programt::const_targett pc,
167-
const goto_programt::const_targett limit)
168-
{
169-
PRECONDITION(!state.threads.empty());
170-
PRECONDITION(!state.call_stack().empty());
171-
state.source = symex_targett::sourcet(function_id, pc);
172-
state.top().end_of_function=limit;
173-
state.top().calling_location.pc=state.top().end_of_function;
174-
state.symex_target=&target;
175-
176-
const goto_functiont &entry_point_function = get_goto_function(function_id);
177-
178-
state.top().hidden_function = entry_point_function.is_hidden();
179-
180-
auto emplace_safe_pointers_result =
181-
state.safe_pointers.emplace(function_id, local_safe_pointerst{ns});
182-
if(emplace_safe_pointers_result.second)
183-
emplace_safe_pointers_result.first->second(entry_point_function.body);
184-
185-
state.dirty.populate_dirty_for_function(function_id, entry_point_function);
186-
187-
symex_transition(state, state.source.pc, false);
188-
}
189-
190162
static void
191163
switch_to_thread(goto_symex_statet &state, const unsigned int thread_nb)
192164
{
@@ -305,50 +277,69 @@ void goto_symext::resume_symex_from_saved_state(
305277
new_symbol_table);
306278
}
307279

308-
void goto_symext::initialize_entry_point_state(
309-
const get_goto_functiont &get_goto_function,
310-
statet &state)
280+
std::unique_ptr<goto_symext::statet> goto_symext::initialize_entry_point_state(
281+
const get_goto_functiont &get_goto_function)
311282
{
283+
const irep_idt entry_point_id = goto_functionst::entry_point();
284+
312285
const goto_functionst::goto_functiont *start_function;
313286
try
314287
{
315-
start_function = &get_goto_function(goto_functionst::entry_point());
288+
start_function = &get_goto_function(entry_point_id);
316289
}
317290
catch(const std::out_of_range &)
318291
{
319292
throw unsupported_operation_exceptiont("the program has no entry point");
320293
}
321294

322-
state.run_validation_checks = symex_config.run_validation_checks;
295+
// create and prepare the state
296+
auto state = util_make_unique<statet>(
297+
symex_targett::sourcet(entry_point_id, start_function->body));
298+
CHECK_RETURN(!state->threads.empty());
299+
CHECK_RETURN(!state->call_stack().empty());
300+
301+
goto_programt::const_targett limit =
302+
std::prev(start_function->body.instructions.end());
303+
state->top().end_of_function = limit;
304+
state->top().calling_location.pc = state->top().end_of_function;
305+
state->top().hidden_function = start_function->is_hidden();
306+
307+
state->symex_target = &target;
308+
309+
state->run_validation_checks = symex_config.run_validation_checks;
323310

324-
initialize_entry_point(
325-
state,
326-
get_goto_function,
327-
goto_functionst::entry_point(),
328-
start_function->body.instructions.begin(),
329-
std::prev(start_function->body.instructions.end()));
311+
// initialize support analyses
312+
auto emplace_safe_pointers_result =
313+
state->safe_pointers.emplace(entry_point_id, local_safe_pointerst{ns});
314+
if(emplace_safe_pointers_result.second)
315+
emplace_safe_pointers_result.first->second(start_function->body);
316+
317+
state->dirty.populate_dirty_for_function(entry_point_id, *start_function);
318+
319+
// make the first step onto the instruction pointed to by the initial program
320+
// counter
321+
symex_transition(*state, state->source.pc, false);
322+
323+
return state;
330324
}
331325

332326
void goto_symext::symex_from_entry_point_of(
333327
const get_goto_functiont &get_goto_function,
334328
symbol_tablet &new_symbol_table)
335329
{
336-
statet state;
337-
initialize_entry_point_state(get_goto_function, state);
330+
auto state = initialize_entry_point_state(get_goto_function);
338331

339-
symex_with_state(
340-
state, get_goto_function, new_symbol_table);
332+
symex_with_state(*state, get_goto_function, new_symbol_table);
341333
}
342334

343335
void goto_symext::initialize_path_storage_from_entry_point_of(
344336
const get_goto_functiont &get_goto_function,
345337
symbol_tablet &new_symbol_table)
346338
{
347-
statet state;
348-
initialize_entry_point_state(get_goto_function, state);
339+
auto state = initialize_entry_point_state(get_goto_function);
349340

350-
path_storaget::patht entry_point_start(target, state);
351-
entry_point_start.state.saved_target = state.source.pc;
341+
path_storaget::patht entry_point_start(target, *state);
342+
entry_point_start.state.saved_target = state->source.pc;
352343
entry_point_start.state.has_saved_next_instruction = true;
353344

354345
path_storage.push(entry_point_start);

src/goto-symex/symex_target.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,9 @@ class symex_targett
3939
// The program counter is an iterator which indicates where the execution
4040
// is in its program sequence
4141
goto_programt::const_targett pc;
42-
bool is_set;
43-
44-
sourcet() : thread_nr(0), function_id(irep_idt()), is_set(false)
45-
{
46-
}
4742

4843
sourcet(const irep_idt &_function_id, goto_programt::const_targett _pc)
49-
: thread_nr(0), function_id(_function_id), pc(_pc), is_set(true)
44+
: thread_nr(0), function_id(_function_id), pc(_pc)
5045
{
5146
}
5247

@@ -55,8 +50,7 @@ class symex_targett
5550
const goto_programt &_goto_program)
5651
: thread_nr(0),
5752
function_id(_function_id),
58-
pc(_goto_program.instructions.begin()),
59-
is_set(true)
53+
pc(_goto_program.instructions.begin())
6054
{
6155
}
6256
};

src/goto-symex/symex_target_equation.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -701,15 +701,12 @@ void symex_target_equationt::SSA_stept::output(
701701
const namespacet &ns,
702702
std::ostream &out) const
703703
{
704-
if(source.is_set)
705-
{
706-
out << "Thread " << source.thread_nr;
704+
out << "Thread " << source.thread_nr;
707705

708-
if(source.pc->source_location.is_not_nil())
709-
out << " " << source.pc->source_location << '\n';
710-
else
711-
out << '\n';
712-
}
706+
if(source.pc->source_location.is_not_nil())
707+
out << " " << source.pc->source_location << '\n';
708+
else
709+
out << '\n';
713710

714711
switch(type)
715712
{
@@ -802,15 +799,12 @@ void symex_target_equationt::SSA_stept::output(
802799

803800
void symex_target_equationt::SSA_stept::output(std::ostream &out) const
804801
{
805-
if(source.is_set)
806-
{
807-
out << "Thread " << source.thread_nr;
802+
out << "Thread " << source.thread_nr;
808803

809-
if(source.pc->source_location.is_not_nil())
810-
out << " " << source.pc->source_location << '\n';
811-
else
812-
out << '\n';
813-
}
804+
if(source.pc->source_location.is_not_nil())
805+
out << " " << source.pc->source_location << '\n';
806+
else
807+
out << '\n';
814808

815809
switch(type)
816810
{

unit/goto-symex/ssa_equation.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ SCENARIO("Validation of well-formed SSA steps", "[core][goto-symex][validate]")
2525
fun_symbol.name = fun_name;
2626
symbol_exprt fun_foo(fun_name, code_type);
2727

28+
goto_programt goto_program;
29+
goto_program.add_instruction(END_FUNCTION);
2830
symex_target_equationt equation;
29-
symex_targett::sourcet empty_source;
31+
symex_targett::sourcet at_end_function(fun_name, goto_program);
3032
equation.SSA_steps.emplace_back(
31-
empty_source, goto_trace_stept::typet::FUNCTION_RETURN);
33+
at_end_function, goto_trace_stept::typet::FUNCTION_RETURN);
3234
auto &step = equation.SSA_steps.back();
3335
step.called_function = fun_name;
3436

0 commit comments

Comments
 (0)