Skip to content

Commit 6a5c9b9

Browse files
martinmartin-cs
authored andcommitted
Create a new kind of abstract interpreter that does function-local analysis
1 parent e0afc7d commit 6a5c9b9

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/analyses/ai.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ bool ai_baset::visit_edge(
410410
return return_value;
411411
}
412412

413-
bool ai_baset::visit_edge_function_call(
413+
bool ai_localt::visit_edge_function_call(
414414
const irep_idt &calling_function_id,
415415
trace_ptrt p_call,
416416
locationt l_return,
@@ -421,11 +421,11 @@ bool ai_baset::visit_edge_function_call(
421421
const namespacet &ns)
422422
{
423423
messaget log(message_handler);
424-
log.progress() << "ai_baset::visit_edge_function_call from "
424+
log.progress() << "ai_localt::visit_edge_function_call from "
425425
<< p_call->current_location()->location_number << " to "
426426
<< l_return->location_number << messaget::eom;
427427

428-
// The default implementation is not interprocedural
428+
// This implementation is not interprocedural
429429
// so the effects of the call are approximated but nothing else
430430
return visit_edge(
431431
calling_function_id,

src/analyses/ai.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ class ai_baset
467467
working_sett &working_set,
468468
const goto_programt &callee,
469469
const goto_functionst &goto_functions,
470-
const namespacet &ns);
470+
const namespacet &ns) = 0;
471471

472472
/// For creating history objects
473473
std::unique_ptr<ai_history_factory_baset> history_factory;
@@ -503,6 +503,41 @@ class ai_baset
503503
message_handlert &message_handler;
504504
};
505505

506+
// Perform function local analysis on all functions in a program.
507+
// No interprocedural analysis other than what a domain does when
508+
// visit()'ing an edge that skips a function call.
509+
class ai_localt : public ai_baset
510+
{
511+
public:
512+
ai_localt(
513+
std::unique_ptr<ai_history_factory_baset> &&hf,
514+
std::unique_ptr<ai_domain_factory_baset> &&df,
515+
std::unique_ptr<ai_storage_baset> &&st,
516+
message_handlert &mh)
517+
: ai_baset(std::move(hf), std::move(df), std::move(st), mh)
518+
{
519+
}
520+
521+
// Handle every function independently
522+
void operator()(const goto_functionst &goto_functions, const namespacet &ns)
523+
override;
524+
void operator()(const abstract_goto_modelt &goto_model) override;
525+
526+
protected:
527+
// Implement the function that handles a single function call edge
528+
// using a single edge that gets the domain to approximate the whole
529+
// function call
530+
bool visit_edge_function_call(
531+
const irep_idt &calling_function_id,
532+
trace_ptrt p_call,
533+
locationt l_return,
534+
const irep_idt &callee_function_id,
535+
working_sett &working_set,
536+
const goto_programt &callee,
537+
const goto_functionst &goto_functions,
538+
const namespacet &ns) override;
539+
};
540+
506541
// Perform interprocedural analysis by simply recursing in the interpreter
507542
// This can lead to a call stack overflow if the domain has a large height
508543
class ai_recursive_interproceduralt : public ai_baset
@@ -523,7 +558,8 @@ class ai_recursive_interproceduralt : public ai_baset
523558
void operator()(const abstract_goto_modelt &goto_model) override;
524559

525560
protected:
526-
// Override the function that handles a single function call edge
561+
// Implement the function that handles a single function call edge
562+
// by a recursive call to fixpoint
527563
bool visit_edge_function_call(
528564
const irep_idt &calling_function_id,
529565
trace_ptrt p_call,

0 commit comments

Comments
 (0)