CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
instrument_preconditions.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Move preconditions of a function
4 to the call-site of the function
5
6Author: Daniel Kroening
7
8Date: September 2017
9
10\*******************************************************************/
11
13
14#include <util/replace_symbol.h>
15
16#include "goto_model.h"
17
18std::vector<goto_programt::const_targett> get_preconditions(
19 const symbol_exprt &function,
20 const goto_functionst &goto_functions)
21{
22 const irep_idt &identifier=function.get_identifier();
23
24 auto f_it=goto_functions.function_map.find(identifier);
25 if(f_it==goto_functions.function_map.end())
26 return {};
27
28 const auto &body=f_it->second.body;
29
30 std::vector<goto_programt::const_targett> result;
31
32 for(auto i_it=body.instructions.begin();
33 i_it!=body.instructions.end();
34 i_it++)
35 {
36 if(i_it->is_location() ||
37 i_it->is_skip())
38 continue; // ignore
39
40 if(
41 i_it->is_assert() &&
42 i_it->source_location().get_property_class() == ID_precondition)
43 {
44 result.push_back(i_it);
45 }
46 else
47 break; // preconditions must be at the front
48 }
49
50 return result;
51}
52
54{
55 for(auto &instruction : goto_program.instructions)
56 {
57 if(instruction.is_location() ||
58 instruction.is_skip())
59 continue; // ignore
60
61 if(
62 instruction.is_assert() &&
63 instruction.source_location().get_property_class() == ID_precondition)
64 {
65 instruction = goto_programt::make_location(instruction.source_location());
66 }
67 else
68 break; // preconditions must be at the front
69 }
70}
71
73 const exprt &lhs,
74 const exprt &function,
75 const exprt::operandst &arguments,
76 const namespacet &ns)
77{
78 PRECONDITION(function.id() == ID_symbol);
79 const symbolt &s = ns.lookup(to_symbol_expr(function));
80 const auto &code_type=to_code_type(s.type);
81 const auto &parameters=code_type.parameters();
82
83 replace_symbolt result;
84 std::size_t count=0;
85 for(const auto &p : parameters)
86 {
87 if(!p.get_identifier().empty() && arguments.size() > count)
88 {
89 const exprt a =
90 typecast_exprt::conditional_cast(arguments[count], p.type());
91 result.insert(symbol_exprt(p.get_identifier(), p.type()), a);
92 }
93 count++;
94 }
95
96 return result;
97}
98
100 const goto_modelt &goto_model,
101 goto_programt &goto_program)
102{
103 const namespacet ns(goto_model.symbol_table);
104
105 for(auto it=goto_program.instructions.begin();
106 it!=goto_program.instructions.end();
107 it++)
108 {
109 if(it->is_function_call())
110 {
111 // does the function we call have preconditions?
112 if(as_const(*it).call_function().id() == ID_symbol)
113 {
114 auto preconditions = get_preconditions(
115 to_symbol_expr(as_const(*it).call_function()),
116 goto_model.goto_functions);
117
118 source_locationt source_location = it->source_location();
119
121 as_const(*it).call_lhs(),
122 as_const(*it).call_function(),
123 as_const(*it).call_arguments(),
124 ns);
125
126 // add before the call, with location of the call
127 for(const auto &p : preconditions)
128 {
129 goto_program.insert_before_swap(it);
130 exprt instance = p->condition();
131 r(instance);
132 source_locationt annotated_location = source_location;
134 annotated_location.set_comment(p->source_location().get_comment());
136 it++;
137 }
138 }
139 }
140 }
141}
142
144{
145 // add at call site
146 for(auto &f_it : goto_model.goto_functions.function_map)
148 goto_model,
149 f_it.second.body);
150
151 // now remove the preconditions
152 for(auto &f_it : goto_model.goto_functions.function_map)
153 remove_preconditions(f_it.second.body);
154 // The above may leave some locations uninitialized, this update is a
155 // sanity to check to ensure the goto model and functions are correct
156 // for later passes.
157 // Note that only the first loop is the one known to leave locations
158 // uninitialized.
159 goto_model.goto_functions.update();
160}
161
163{
164 remove_preconditions(goto_function.body);
165}
166
168{
169 for(auto &f_it : goto_model.goto_functions.function_map)
171}
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
Definition as_const.h:14
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
A collection of goto functions.
function_mapt function_map
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
goto_programt body
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
A generic container class for the GOTO intermediate representation of one function.
instructionst instructions
The list of instructions in the goto program.
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
static instructiont make_location(const source_locationt &l)
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
const irep_idt & id() const
Definition irep.h:388
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Replace a symbol expression by a given expression.
void insert(const class symbol_exprt &old_expr, const exprt &new_expr)
Sets old_expr to be replaced by new_expr if we don't already have a replacement; otherwise does nothi...
Expression to hold a symbol (variable)
Definition std_expr.h:131
const irep_idt & get_identifier() const
Definition std_expr.h:160
Symbol table entry.
Definition symbol.h:28
typet type
Type of symbol.
Definition symbol.h:31
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition std_expr.h:2081
Symbol Table + CFG.
std::vector< goto_programt::const_targett > get_preconditions(const symbol_exprt &function, const goto_functionst &goto_functions)
void remove_preconditions(goto_programt &goto_program)
replace_symbolt actuals_replace_map(const exprt &lhs, const exprt &function, const exprt::operandst &arguments, const namespacet &ns)
void instrument_preconditions(const goto_modelt &goto_model, goto_programt &goto_program)
static int8_t r
Definition irep_hash.h:60
#define PRECONDITION(CONDITION)
Definition invariant.h:463
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788