Skip to content

Commit 1063983

Browse files
author
Daniel Kroening
authored
Merge pull request #3276 from diffblue/called_function
introduce 'called_function' into goto traces [blocks: #3126]
2 parents d4d00ab + 05eb134 commit 1063983

18 files changed

+115
-79
lines changed

regression/cbmc/trace_show_function_calls/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ main.c
44
^EXIT=10$
55
^SIGNAL=0$
66
Function call: function_to_call\(-2147483647\) \(depth 2\)
7-
Function return: function_to_call \(depth 1\)
7+
Function return from function_to_call \(depth 1\)
88
Function call: function_to_call\(-2\) \(depth 2\)
99
^VERIFICATION FAILED$
1010
--

src/cbmc/symex_bmc.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ void symex_bmct::symex_step(
6565

6666
goto_symext::symex_step(get_goto_function, state);
6767

68-
if(record_coverage &&
69-
// avoid an invalid iterator in state.source.pc
70-
(!cur_pc->is_end_function() ||
71-
cur_pc->function!=goto_functionst::entry_point()))
68+
if(
69+
record_coverage &&
70+
// avoid an invalid iterator in state.source.pc
71+
(!cur_pc->is_end_function() ||
72+
state.source.function != goto_functionst::entry_point()))
7273
{
7374
// forward goto will effectively be covered via phi function,
7475
// which does not invoke symex_step; as symex_step is called

src/goto-programs/goto_trace.cpp

+14-14
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ void goto_trace_stept::output(
8383

8484
if(is_assert() || is_assume() || is_goto())
8585
out << " (" << cond_value << ')';
86-
else if(is_function_call() || is_function_return())
87-
out << ' ' << function_identifier;
86+
else if(is_function_call())
87+
out << ' ' << called_function;
8888

8989
if(hidden)
9090
out << " hidden";
@@ -344,8 +344,7 @@ void show_full_goto_trace(
344344
out << " " << messaget::red << step.comment << messaget::reset << '\n';
345345

346346
if(step.pc->is_assert())
347-
out << " " << from_expr(ns, step.pc->function, step.pc->guard)
348-
<< '\n';
347+
out << " " << from_expr(ns, step.function, step.pc->guard) << '\n';
349348

350349
out << '\n';
351350
}
@@ -360,8 +359,7 @@ void show_full_goto_trace(
360359
out << " " << step.pc->source_location << '\n';
361360

362361
if(step.pc->is_assume())
363-
out << " " << from_expr(ns, step.pc->function, step.pc->guard)
364-
<< '\n';
362+
out << " " << from_expr(ns, step.function, step.pc->guard) << '\n';
365363

366364
out << '\n';
367365
}
@@ -431,7 +429,8 @@ void show_full_goto_trace(
431429
{
432430
if(l_it!=step.io_args.begin())
433431
out << ';';
434-
out << ' ' << from_expr(ns, step.pc->function, *l_it);
432+
433+
out << ' ' << from_expr(ns, step.function, *l_it);
435434

436435
// the binary representation
437436
out << " (" << trace_numeric_value(*l_it, ns, options) << ')';
@@ -453,7 +452,8 @@ void show_full_goto_trace(
453452
{
454453
if(l_it!=step.io_args.begin())
455454
out << ';';
456-
out << ' ' << from_expr(ns, step.pc->function, *l_it);
455+
456+
out << ' ' << from_expr(ns, step.function, *l_it);
457457

458458
// the binary representation
459459
out << " (" << trace_numeric_value(*l_it, ns, options) << ')';
@@ -466,7 +466,7 @@ void show_full_goto_trace(
466466
function_depth++;
467467
if(options.show_function_calls)
468468
{
469-
out << "\n#### Function call: " << step.function_identifier;
469+
out << "\n#### Function call: " << step.called_function;
470470
out << '(';
471471

472472
bool first = true;
@@ -477,7 +477,7 @@ void show_full_goto_trace(
477477
else
478478
out << ", ";
479479

480-
out << from_expr(ns, step.function_identifier, arg);
480+
out << from_expr(ns, step.function, arg);
481481
}
482482

483483
out << ") (depth " << function_depth << ") ####\n";
@@ -488,8 +488,8 @@ void show_full_goto_trace(
488488
function_depth--;
489489
if(options.show_function_calls)
490490
{
491-
out << "\n#### Function return: " << step.function_identifier
492-
<< " (depth " << function_depth << ") ####\n";
491+
out << "\n#### Function return from " << step.function << " (depth "
492+
<< function_depth << ") ####\n";
493493
}
494494
break;
495495

@@ -561,7 +561,7 @@ void show_goto_stack_trace(
561561
}
562562
else if(step.is_function_call())
563563
{
564-
out << " " << step.function_identifier;
564+
out << " " << step.called_function;
565565
out << '(';
566566

567567
bool first = true;
@@ -572,7 +572,7 @@ void show_goto_stack_trace(
572572
else
573573
out << ", ";
574574

575-
out << from_expr(ns, step.function_identifier, arg);
575+
out << from_expr(ns, step.function, arg);
576576
}
577577

578578
out << ')';

src/goto-programs/goto_trace.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class goto_trace_stept
8686
enum class assignment_typet { STATE, ACTUAL_PARAMETER };
8787
assignment_typet assignment_type;
8888

89+
// The instruction that created this step
90+
// (function calls are in the caller, function returns are in the callee)
91+
irep_idt function;
8992
goto_programt::const_targett pc;
9093

9194
// this transition done by given thread number
@@ -113,8 +116,8 @@ class goto_trace_stept
113116
io_argst io_args;
114117
bool formatted;
115118

116-
// for function call/return
117-
irep_idt function_identifier;
119+
// for function calls
120+
irep_idt called_function;
118121

119122
// for function call
120123
std::vector<exprt> function_arguments;

src/goto-programs/graphml_witness.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace)
284284
{
285285
xmlt &val=edge.new_element("data");
286286
val.set_attribute("key", "assumption");
287-
val.data=from_expr(ns, it->pc->function, it->full_lhs)+" = "+
288-
from_expr(ns, it->pc->function, it->full_lhs_value)+";";
287+
val.data = from_expr(ns, it->function, it->full_lhs) + " = " +
288+
from_expr(ns, it->function, it->full_lhs_value) + ";";
289289

290290
xmlt &val_s=edge.new_element("data");
291291
val_s.set_attribute("key", "assumption.scope");
@@ -296,10 +296,9 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace)
296296
{
297297
xmlt &val=edge.new_element("data");
298298
val.set_attribute("key", "sourcecode");
299-
const std::string cond =
300-
from_expr(ns, it->pc->function, it->cond_expr);
301-
const std::string neg_cond=
302-
from_expr(ns, it->pc->function, not_exprt(it->cond_expr));
299+
const std::string cond = from_expr(ns, it->function, it->cond_expr);
300+
const std::string neg_cond =
301+
from_expr(ns, it->function, not_exprt(it->cond_expr));
303302
val.data="["+(it->cond_value ? cond : neg_cond)+"]";
304303

305304
#if 0
@@ -481,7 +480,7 @@ void graphml_witnesst::operator()(const symex_target_equationt &equation)
481480
xmlt &val=edge.new_element("data");
482481
val.set_attribute("key", "sourcecode");
483482
const std::string cond =
484-
from_expr(ns, it->source.pc->function, it->cond_expr);
483+
from_expr(ns, it->source.function, it->cond_expr);
485484
val.data="["+cond+"]";
486485
}
487486

src/goto-programs/interpreter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ void interpretert::execute_function_call()
759759
const memory_cellt &cell=memory[address];
760760
#endif
761761
const irep_idt &identifier = address_to_identifier(address);
762-
trace_step.function_identifier = identifier;
762+
trace_step.called_function = identifier;
763763

764764
const goto_functionst::function_mapt::const_iterator f_it=
765765
goto_functions.function_map.find(identifier);

src/goto-programs/json_goto_trace.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,14 @@ void convert_return(
277277
json_call_return["internal"] = jsont::json_boolean(step.internal);
278278
json_call_return["thread"] = json_numbert(std::to_string(step.thread_nr));
279279

280-
const symbolt &symbol = ns.lookup(step.function_identifier);
280+
const irep_idt &function_identifier =
281+
(step.type == goto_trace_stept::typet::FUNCTION_CALL) ? step.called_function
282+
: step.function;
283+
284+
const symbolt &symbol = ns.lookup(function_identifier);
281285
json_objectt &json_function = json_call_return["function"].make_object();
282286
json_function["displayName"] = json_stringt(symbol.display_name());
283-
json_function["identifier"] = json_stringt(step.function_identifier);
287+
json_function["identifier"] = json_stringt(function_identifier);
284288
json_function["sourceLocation"] = json(symbol.location);
285289

286290
if(!location.is_null())

src/goto-programs/xml_goto_trace.cpp

+25-8
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void convert(
139139
for(const auto &arg : step.io_args)
140140
{
141141
xml_output.new_element("value").data =
142-
from_expr(ns, step.pc->function, arg);
142+
from_expr(ns, step.function, arg);
143143
xml_output.new_element("value_expression").
144144
new_element(xml(arg, ns));
145145
}
@@ -158,7 +158,7 @@ void convert(
158158
for(const auto &arg : step.io_args)
159159
{
160160
xml_input.new_element("value").data =
161-
from_expr(ns, step.pc->function, arg);
161+
from_expr(ns, step.function, arg);
162162
xml_input.new_element("value_expression").
163163
new_element(xml(arg, ns));
164164
}
@@ -169,23 +169,40 @@ void convert(
169169
break;
170170

171171
case goto_trace_stept::typet::FUNCTION_CALL:
172+
{
173+
std::string tag = "function_call";
174+
xmlt &xml_call_return = dest.new_element(tag);
175+
176+
xml_call_return.set_attribute_bool("hidden", step.hidden);
177+
xml_call_return.set_attribute("thread", std::to_string(step.thread_nr));
178+
xml_call_return.set_attribute("step_nr", std::to_string(step.step_nr));
179+
180+
const symbolt &symbol = ns.lookup(step.called_function);
181+
xmlt &xml_function = xml_call_return.new_element("function");
182+
xml_function.set_attribute(
183+
"display_name", id2string(symbol.display_name()));
184+
xml_function.set_attribute("identifier", id2string(symbol.name));
185+
xml_function.new_element() = xml(symbol.location);
186+
187+
if(xml_location.name != "")
188+
xml_call_return.new_element().swap(xml_location);
189+
}
190+
break;
191+
172192
case goto_trace_stept::typet::FUNCTION_RETURN:
173193
{
174-
std::string tag=
175-
(step.type==goto_trace_stept::typet::FUNCTION_CALL)?
176-
"function_call":"function_return";
194+
std::string tag = "function_return";
177195
xmlt &xml_call_return=dest.new_element(tag);
178196

179197
xml_call_return.set_attribute_bool("hidden", step.hidden);
180198
xml_call_return.set_attribute("thread", std::to_string(step.thread_nr));
181199
xml_call_return.set_attribute("step_nr", std::to_string(step.step_nr));
182200

183-
const symbolt &symbol = ns.lookup(step.function_identifier);
201+
const symbolt &symbol = ns.lookup(step.function);
184202
xmlt &xml_function=xml_call_return.new_element("function");
185203
xml_function.set_attribute(
186204
"display_name", id2string(symbol.display_name()));
187-
xml_function.set_attribute(
188-
"identifier", id2string(step.function_identifier));
205+
xml_function.set_attribute("identifier", id2string(step.function));
189206
xml_function.new_element()=xml(symbol.location);
190207

191208
if(xml_location.name!="")

src/goto-symex/build_goto_trace.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void update_internal_field(
153153
}
154154

155155
// set internal field to _start function-return step
156-
if(SSA_step.source.pc->function==goto_functionst::entry_point())
156+
if(SSA_step.source.function == goto_functionst::entry_point())
157157
{
158158
// "__CPROVER_*" function calls in __CPROVER_start are already marked as
159159
// internal. Don't mark any other function calls (i.e. "main"), function
@@ -299,13 +299,14 @@ void build_goto_trace(
299299

300300
goto_trace_step.thread_nr = SSA_step.source.thread_nr;
301301
goto_trace_step.pc = SSA_step.source.pc;
302+
goto_trace_step.function = SSA_step.source.function;
302303
goto_trace_step.comment = SSA_step.comment;
303304
goto_trace_step.type = SSA_step.type;
304305
goto_trace_step.hidden = SSA_step.hidden;
305306
goto_trace_step.format_string = SSA_step.format_string;
306307
goto_trace_step.io_id = SSA_step.io_id;
307308
goto_trace_step.formatted = SSA_step.formatted;
308-
goto_trace_step.function_identifier = SSA_step.function_identifier;
309+
goto_trace_step.called_function = SSA_step.called_function;
309310
goto_trace_step.function_arguments = SSA_step.converted_function_arguments;
310311

311312
for(auto &arg : goto_trace_step.function_arguments)

src/goto-symex/goto_symex.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,13 @@ class goto_symext
148148
/// procedure.
149149
/// \param state Symex state to start with.
150150
/// \param goto_functions GOTO model to symex.
151+
/// \param function_identifier The function with the instruction range
151152
/// \param first Entry point in form of a first instruction.
152153
/// \param limit Final instruction, which itself will not be symexed.
153154
virtual void symex_instruction_range(
154155
statet &,
155156
const goto_functionst &,
157+
const irep_idt &function_identifier,
156158
goto_programt::const_targett first,
157159
goto_programt::const_targett limit);
158160

@@ -162,11 +164,13 @@ class goto_symext
162164
/// procedure.
163165
/// \param state Symex state to start with.
164166
/// \param get_goto_function retrieves a function body
167+
/// \param function_identifier The function with the instruction range
165168
/// \param first Entry point in form of a first instruction.
166169
/// \param limit Final instruction, which itself will not be symexed.
167170
virtual void symex_instruction_range(
168171
statet &state,
169172
const get_goto_functiont &get_goto_function,
173+
const irep_idt &function_identifier,
170174
goto_programt::const_targett first,
171175
goto_programt::const_targett limit);
172176

@@ -183,13 +187,15 @@ class goto_symext
183187
/// Initialise the symbolic execution and the given state with <code>pc</code>
184188
/// as entry point.
185189
/// \param state Symex state to initialise.
186-
/// \param goto_functions GOTO model to symex.
190+
/// \param get_goto_function producer for GOTO functions
191+
/// \param function_identifier The function in which the instructions are
187192
/// \param pc first instruction to symex
188193
/// \param limit final instruction, which itself will not
189194
/// be symexed.
190195
void initialize_entry_point(
191196
statet &state,
192197
const get_goto_functiont &get_goto_function,
198+
const irep_idt &function_identifier,
193199
goto_programt::const_targett pc,
194200
goto_programt::const_targett limit);
195201

src/goto-symex/show_program.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void show_program(const namespacet &ns, const symex_target_equationt &equation)
2929
{
3030
std::cout << "// " << step.source.pc->location_number << " ";
3131
std::cout << step.source.pc->source_location.as_string() << "\n";
32-
const irep_idt &function = step.source.pc->function;
32+
const irep_idt &function = step.source.function;
3333

3434
if(step.is_assignment())
3535
{

src/goto-symex/symex_builtin_functions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ void goto_symext::symex_allocate(
5555

5656
exprt size=code.op0();
5757
typet object_type=nil_typet();
58-
auto function_symbol = outer_symbol_table.lookup(state.source.pc->function);
59-
INVARIANT(function_symbol, "function associated with instruction not found");
58+
auto function_symbol = outer_symbol_table.lookup(state.source.function);
59+
INVARIANT(function_symbol, "function associated with allocation not found");
6060
const irep_idt &mode = function_symbol->mode;
6161

6262
// is the type given?

src/goto-symex/symex_dereference.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ void goto_symext::dereference_rec(
258258

259259
if(state.threads.size() == 1)
260260
{
261-
const irep_idt &expr_function = state.source.pc->function;
261+
const irep_idt &expr_function = state.source.function;
262262
if(!expr_function.empty())
263263
{
264264
state.get_original_name(to_check);

0 commit comments

Comments
 (0)