Skip to content

Commit b949c68

Browse files
authored
Merge pull request diffblue#143 from diffblue/marek/slicer_integration_PR
Slicer integration (C++ part).
2 parents 375e9b6 + 6e7710a commit b949c68

File tree

2 files changed

+115
-9
lines changed

2 files changed

+115
-9
lines changed

src/taint-slicer/instrumenter.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,28 +216,40 @@ std::size_t taint_instrumentert::instrument_location(
216216
cond=and_exprt(cond,
217217
symbol_exprt(from_tokens_to_vars.at(it->get_token_name()),
218218
typet(ID_bool)));
219-
instrumentation_code.add_instruction()->make_goto(
220-
instrumention_tail_instruction, not_exprt(cond));
219+
auto iit=instrumentation_code.add_instruction();
220+
iit->make_goto(instrumention_tail_instruction, not_exprt(cond));
221+
iit->function=loc.get_function_id();
221222
}
222223
// Now we instrument "turn on" assignments of state variables.
223224
for(const auto &arg_token : loc.get_turn_on())
224-
instrumentation_code.add_instruction(ASSIGN)->code=code_assignt(
225-
symbol_exprt(from_tokens_to_vars.at(arg_token.get_token_name()),
226-
typet(ID_bool)),
225+
{
226+
auto iit=instrumentation_code.add_instruction(ASSIGN);
227+
iit->code=code_assignt(
228+
symbol_exprt(
229+
from_tokens_to_vars.at(arg_token.get_token_name()),
230+
typet(ID_bool)),
227231
constant_exprt(ID_true, typet(ID_bool)));
228-
// Now we instrument "turn of" assignments of state variables.
232+
iit->function=loc.get_function_id();
233+
}
234+
// Now we instrument "turn off" assignments of state variables.
229235
for(const auto &arg_token : loc.get_turn_off())
230-
instrumentation_code.add_instruction(ASSIGN)->code=code_assignt(
231-
symbol_exprt(from_tokens_to_vars.at(arg_token.get_token_name()),
232-
typet(ID_bool)),
236+
{
237+
auto iit=instrumentation_code.add_instruction(ASSIGN);
238+
iit->code=code_assignt(
239+
symbol_exprt(
240+
from_tokens_to_vars.at(arg_token.get_token_name()),
241+
typet(ID_bool)),
233242
constant_exprt(ID_false, typet(ID_bool)));
243+
iit->function=loc.get_function_id();
244+
}
234245
if(props.get_sinks().count(lid))
235246
{
236247
// This instrumentation location a sink location -> we have to instrument
237248
// also assertion representing the taint issue (the condition is FALSE).
238249
auto instr_it=instrumentation_code.add_instruction();
239250
instr_it->make_assertion(constant_exprt(ID_false, typet(ID_bool)));
240251
instr_it->source_location=loc.get_instruction_id()->source_location;
252+
instr_it->function=loc.get_function_id();
241253
}
242254
// Now we can move the prepared instrumentation code into the function.
243255
const std::size_t shift=instrumentation_code.instructions.size();

src/taint-slicer/slicing_tasks_builder.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,75 @@ the instrumenter.
3131
#include <util/msgstream.h>
3232
#include <summaries/summary_dump.h>
3333
#include <exception>
34+
#include <iostream>
35+
36+
37+
/*******************************************************************\
38+
39+
Function: remove_calls_to_functions_without_bodies
40+
41+
Inputs:
42+
43+
Outputs:
44+
45+
Purpose: The function remove all functions without bodies from the passed
46+
goto_functions and symbol_table and also all call instructions
47+
to those functions.
48+
49+
\*******************************************************************/
50+
static void remove_calls_to_functions_without_bodies(
51+
goto_functionst &goto_functions,
52+
symbol_tablet &symbol_table)
53+
{
54+
std::set<irep_idt> fns_without_bodies;
55+
for(auto &fname_prog : goto_functions.function_map)
56+
{
57+
std::vector<goto_programt::targett> to_remove;
58+
for(auto it=fname_prog.second.body.instructions.begin();
59+
it!=fname_prog.second.body.instructions.end();
60+
++it)
61+
{
62+
if(it->type==FUNCTION_CALL)
63+
{
64+
auto fn_call=to_code_function_call(it->code);
65+
if(fn_call.function().id()==ID_symbol)
66+
{
67+
auto s=to_symbol_expr(fn_call.function());
68+
auto fit=goto_functions.function_map.find(s.get_identifier());
69+
if(fit==goto_functions.function_map.end() ||
70+
fit->second.body.instructions.empty())
71+
{
72+
fns_without_bodies.insert(s.get_identifier());
73+
to_remove.push_back(it);
74+
++it;
75+
if(it!=fname_prog.second.body.instructions.end() &&
76+
it->type==ASSIGN)
77+
{
78+
auto asgn=to_code_assign(it->code);
79+
if(asgn.lhs().id()==ID_symbol)
80+
{
81+
auto lhs=to_symbol_expr(asgn.lhs());
82+
if(as_string(lhs.get_identifier())==
83+
as_string(s.get_identifier())+RETURN_VALUE_SUFFIX)
84+
{
85+
to_remove.push_back(it);
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
}
93+
for(auto &tgt : to_remove)
94+
{
95+
assert(tgt->targets.empty());
96+
tgt->make_skip();
97+
}
98+
}
99+
for(const auto &fn_name : fns_without_bodies)
100+
symbol_table.remove(fn_name);
101+
}
102+
34103

35104
/*******************************************************************\
36105
@@ -55,6 +124,7 @@ Function: add_nondet_retval_assignments_after_calls
55124
\*******************************************************************/
56125
static void add_nondet_retval_assignments_after_calls(
57126
goto_programt &goto_program,
127+
const irep_idt &caller_name,
58128
const std::string &callee_name,
59129
const typet &callee_ret_type)
60130
{
@@ -75,6 +145,7 @@ static void add_nondet_retval_assignments_after_calls(
75145
instr_it->code=code_assignt(
76146
symbol_exprt(callee_name+RETURN_VALUE_SUFFIX,callee_ret_type),
77147
side_effect_expr_nondett(callee_ret_type));
148+
instr_it->function=caller_name;
78149
}
79150
}
80151
}
@@ -156,6 +227,7 @@ std::pair<taint_slicing_taskt,std::string> build_slicing_task(
156227
if(fid_fn.second.body_available())
157228
add_nondet_retval_assignments_after_calls(
158229
fid_fn.second.body,
230+
fid_fn.first,
159231
fid,
160232
symbol_table.lookup(fid+RETURN_VALUE_SUFFIX).type);
161233
}
@@ -201,6 +273,11 @@ std::pair<taint_slicing_taskt,std::string> build_slicing_task(
201273
}
202274
}
203275

276+
// And we do the final clean-up: we remove all functions without bodies
277+
// from the goto_functions and symbol_table and also all call instructions
278+
// to those functions.
279+
remove_calls_to_functions_without_bodies(goto_functions, symbol_table);
280+
204281
// Finally, we have to "update" the GOTO program - mandatory step fixing
205282
// uniquenes of program locations, etc.
206283
goto_functions.update();
@@ -230,6 +307,23 @@ std::pair<taint_slicing_taskt,std::string> build_slicing_task(
230307
std::atoi(loc.get_line().c_str())});
231308
}
232309

310+
// Check for issues in the program w.r.t. requirements of the slicer
311+
// and try to fix them.
312+
for(auto &fname_prog : goto_functions.function_map)
313+
for(auto &I : fname_prog.second.body.instructions)
314+
if(I.function.empty())
315+
{
316+
logger->status()
317+
<< "WARNING: Instruction without 'function' reference:\n"
318+
<< " loc.: " << I.location_number << "\n"
319+
<< " func: " << fname_prog.first << "\n"
320+
<< " code: ";
321+
dump_instruction_code_in_html(
322+
I, namespacet(symbol_table), logger->status());
323+
logger->status() << "\n Fixing the issue.\n";
324+
I.function=fname_prog.first;
325+
}
326+
233327
// Finally save the constructed slicing task on the disc as GOTO program
234328
// binary.
235329
const bool fail=write_goto_binary(

0 commit comments

Comments
 (0)