CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
value_set_analysis_fi.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Value Set Propagation (Flow Insensitive)
4
5Author: Daniel Kroening, kroening@kroening.com
6 CM Wintersteiger
7
8\*******************************************************************/
9
12
14
15#include <util/c_types.h>
16#include <util/namespace.h>
17#include <util/pointer_expr.h>
19
21 const goto_programt &goto_program)
22{
23 baset::initialize(goto_program);
24 add_vars(goto_program);
25}
26
28 const goto_functionst &goto_functions)
29{
30 baset::initialize(goto_functions);
31 add_vars(goto_functions);
32}
33
35 const goto_programt &goto_program)
36{
37 typedef std::list<value_set_fit::entryt> entry_listt;
38
39 // get the globals
42
43 // get the locals
45 goto_program.get_decl_identifiers(locals);
46
47 // cache the list for the locals to speed things up
48 typedef std::unordered_map<irep_idt, entry_listt> entry_cachet;
50
52
53 for(goto_programt::instructionst::const_iterator
54 i_it=goto_program.instructions.begin();
55 i_it!=goto_program.instructions.end();
56 i_it++)
57 {
59
60 for(goto_programt::decl_identifierst::const_iterator
61 l_it=locals.begin();
62 l_it!=locals.end();
63 l_it++)
64 {
65 // cache hit?
66 entry_cachet::const_iterator e_it=entry_cache.find(*l_it);
67
68 if(e_it==entry_cache.end())
69 {
70 const symbolt &symbol=ns.lookup(*l_it);
71
72 std::list<value_set_fit::entryt> &entries=entry_cache[*l_it];
73 get_entries(symbol, entries);
74 v.add_vars(entries);
75 }
76 else
77 v.add_vars(e_it->second);
78 }
79 }
80}
81
83 const symbolt &symbol,
84 std::list<value_set_fit::entryt> &dest)
85{
86 get_entries_rec(symbol.name, "", symbol.type, dest);
87}
88
90 const irep_idt &identifier,
91 const std::string &suffix,
92 const typet &type,
93 std::list<value_set_fit::entryt> &dest)
94{
95 if(type.id() == ID_struct_tag || type.id() == ID_union_tag)
96 {
97 const auto &components =
98 ns.follow_tag(to_struct_or_union_tag_type(type)).components();
99 for(const auto &c : components)
100 {
102 identifier, suffix + "." + id2string(c.get_name()), c.type(), dest);
103 }
104 }
105 else if(type.id() == ID_struct || type.id() == ID_union)
106 {
107 const auto &components = to_struct_union_type(type).components();
108 for(const auto &c : components)
109 {
111 identifier, suffix + "." + id2string(c.get_name()), c.type(), dest);
112 }
113 }
114 else if(type.id() == ID_array)
115 {
117 identifier, suffix + "[]", to_array_type(type).element_type(), dest);
118 }
119 else if(check_type(type))
120 {
121 dest.push_back(value_set_fit::entryt(identifier, suffix));
122 }
123}
124
126 const goto_functionst &goto_functions)
127{
128 // get the globals
129 std::list<value_set_fit::entryt> globals;
131
133 v.add_vars(globals);
134
135 for(const auto &gf_entry : goto_functions.function_map)
136 {
137 // get the locals
138 std::set<irep_idt> locals;
139 get_local_identifiers(gf_entry.second, locals);
140
141 for(auto l : locals)
142 {
143 const symbolt &symbol=ns.lookup(l);
144
145 std::list<value_set_fit::entryt> entries;
146 get_entries(symbol, entries);
147 v.add_vars(entries);
148 }
149 }
150}
151
153 std::list<value_set_fit::entryt> &dest)
154{
155 // static ones
156 for(const auto &symbol_pair : ns.get_symbol_table().symbols)
157 {
158 if(symbol_pair.second.is_lvalue && symbol_pair.second.is_static_lifetime)
159 {
160 get_entries(symbol_pair.second, dest);
161 }
162 }
163}
164
166{
167 if(type.id()==ID_pointer)
168 {
169 switch(track_options)
170 {
172 { return true; break; }
174 {
175 if(type.id()==ID_pointer)
176 {
177 const typet *t = &type;
178 while(t->id() == ID_pointer)
179 t = &(to_pointer_type(*t).base_type());
180
181 return (t->id()==ID_code);
182 }
183
184 break;
185 }
186 default: // don't track.
187 break;
188 }
189 }
190 else if(type.id()==ID_struct ||
191 type.id()==ID_union)
192 {
193 for(const auto &c : to_struct_union_type(type).components())
194 {
195 if(check_type(c.type()))
196 return true;
197 }
198 }
199 else if(type.id()==ID_array)
200 return check_type(to_array_type(type).element_type());
201 else if(type.id() == ID_struct_tag)
202 return check_type(ns.follow_tag(to_struct_tag_type(type)));
203 else if(type.id() == ID_union_tag)
204 return check_type(ns.follow_tag(to_union_tag_type(type)));
205
206 return false;
207}
208
210 const irep_idt &function_id,
212 const exprt &expr)
213{
215 state.value_set.function_numbering.number(function_id);
217 state.value_set.function_numbering.number(function_id);
218 state.value_set.from_target_index = l->location_number;
219 state.value_set.to_target_index = l->location_number;
220 return state.value_set.get_value_set(expr, ns);
221}
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition c_types.h:224
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
goto_programt::const_targett locationt
virtual void initialize(const goto_programt &)
A collection of goto functions.
function_mapt function_map
A generic container class for the GOTO intermediate representation of one function.
instructionst instructions
The list of instructions in the goto program.
std::set< irep_idt > decl_identifierst
void get_decl_identifiers(decl_identifierst &decl_identifiers) const
get the variables in decl statements
const irep_idt & id() const
Definition irep.h:388
Symbol table entry.
Definition symbol.h:28
typet type
Type of symbol.
Definition symbol.h:31
irep_idt name
The unique identifier.
Definition symbol.h:40
The type of an expression, extends irept.
Definition type.h:29
bool check_type(const typet &type)
std::vector< exprt > get_values(const irep_idt &function_id, locationt l, const exprt &expr) override
void get_entries(const symbolt &symbol, std::list< value_set_fit::entryt > &dest)
void add_vars(const goto_functionst &goto_functions)
void get_entries_rec(const irep_idt &identifier, const std::string &suffix, const typet &type, std::list< value_set_fit::entryt > &dest)
void get_globals(std::list< value_set_fit::entryt > &dest)
void initialize(const goto_programt &goto_program) override
static numberingt< irep_idt > function_numbering
void add_vars(const std::list< entryt > &vars)
std::vector< exprt > get_value_set(const exprt &expr, const namespacet &ns) const
unsigned from_function
unsigned to_function
unsigned from_target_index
unsigned to_target_index
void get_local_identifiers(const goto_functiont &goto_function, std::set< irep_idt > &dest)
Return in dest the identifiers of the local variables declared in the goto_function and the identifie...
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
API to expression classes for Pointers.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const struct_or_union_tag_typet & to_struct_or_union_tag_type(const typet &type)
Cast a typet to a struct_or_union_tag_typet.
Definition std_types.h:478
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition std_types.h:214
Author: Diffblue Ltd.
Value Set Propagation (flow insensitive)