CBMC
value_set_analysis_fi.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Value Set Propagation (Flow Insensitive)
4 
5 Author: Daniel Kroening, kroening@kroening.com
6  CM Wintersteiger
7 
8 \*******************************************************************/
9 
12 
13 #include "value_set_analysis_fi.h"
14 
15 #include <util/c_types.h>
16 #include <util/namespace.h>
17 #include <util/pointer_expr.h>
18 #include <util/symbol_table_base.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
40  entry_listt globals;
41  get_globals(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;
49  entry_cachet entry_cache;
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  {
58  v.add_vars(globals);
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 =
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;
130  get_globals(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  {
171  case TRACK_ALL_POINTERS:
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)
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 {
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
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:827
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.
Definition: goto_program.h:73
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:622
std::set< irep_idt > decl_identifierst
Definition: goto_program.h:853
void get_decl_identifiers(decl_identifierst &decl_identifiers) const
get the variables in decl statements
const irep_idt & id() const
Definition: irep.h:388
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
const symbol_table_baset & get_symbol_table() const
Return first symbol table registered with the namespace.
Definition: namespace.h:126
number_type number(const key_type &a)
Definition: numbering.h:37
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
const componentst & components() const
Definition: std_types.h:147
const symbolst & symbols
Read-only field, used to look up symbols given their names.
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
Definition: value_set_fi.h:42
void add_vars(const std::list< entryt > &vars)
Definition: value_set_fi.h:237
std::vector< exprt > get_value_set(const exprt &expr, const namespacet &ns) const
unsigned from_function
Definition: value_set_fi.h:39
unsigned to_function
Definition: value_set_fi.h:39
unsigned from_target_index
Definition: value_set_fi.h:40
unsigned to_target_index
Definition: value_set_fi.h:40
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.
Definition: pointer_expr.h:93
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
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
Author: Diffblue Ltd.
Value Set Propagation (flow insensitive)