CBMC
find_symbols.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "find_symbols.h"
10 
11 #include "c_types.h"
12 #include "expr_iterator.h"
13 #include "range.h"
14 #include "std_expr.h"
15 
17 enum class symbol_kindt
18 {
20  F_TYPE,
25  F_EXPR,
29  F_ALL
30 };
31 
32 static bool find_symbols(
34  const typet &,
35  std::function<bool(const symbol_exprt &)>,
36  std::unordered_set<irep_idt> &bindings);
37 
38 static bool find_symbols(
39  symbol_kindt kind,
40  const exprt &src,
41  std::function<bool(const symbol_exprt &)> op,
42  std::unordered_set<irep_idt> &bindings)
43 {
44  if(kind == symbol_kindt::F_EXPR_FREE)
45  {
46  if(src.id() == ID_forall || src.id() == ID_exists || src.id() == ID_lambda)
47  {
48  const auto &binding_expr = to_binding_expr(src);
49  std::unordered_set<irep_idt> new_bindings{bindings};
50  for(const auto &v : binding_expr.variables())
51  new_bindings.insert(v.get_identifier());
52 
53  if(!find_symbols(kind, binding_expr.where(), op, new_bindings))
54  return false;
55 
56  return find_symbols(kind, binding_expr.type(), op, bindings);
57  }
58  else if(src.id() == ID_let)
59  {
60  const auto &let_expr = to_let_expr(src);
61  std::unordered_set<irep_idt> new_bindings{bindings};
62  for(const auto &v : let_expr.variables())
63  new_bindings.insert(v.get_identifier());
64 
65  if(!find_symbols(kind, let_expr.where(), op, new_bindings))
66  return false;
67 
68  if(!find_symbols(kind, let_expr.op1(), op, new_bindings))
69  return false;
70 
71  return find_symbols(kind, let_expr.type(), op, bindings);
72  }
73  }
74 
75  forall_operands(it, src)
76  {
77  if(!find_symbols(kind, *it, op, bindings))
78  return false;
79  }
80 
81  if(!find_symbols(kind, src.type(), op, bindings))
82  return false;
83 
84  if(src.id() == ID_symbol)
85  {
86  const symbol_exprt &s = to_symbol_expr(src);
87 
88  if(kind == symbol_kindt::F_ALL || kind == symbol_kindt::F_EXPR)
89  {
90  if(!op(s))
91  return false;
92  }
93  else if(kind == symbol_kindt::F_EXPR_FREE)
94  {
95  if(bindings.find(s.get_identifier()) == bindings.end() && !op(s))
96  return false;
97  }
98  }
99 
100  const irept &c_sizeof_type=src.find(ID_C_c_sizeof_type);
101 
102  if(
103  c_sizeof_type.is_not_nil() &&
104  !find_symbols(
105  kind, static_cast<const typet &>(c_sizeof_type), op, bindings))
106  {
107  return false;
108  }
109 
110  const irept &va_arg_type=src.find(ID_C_va_arg_type);
111 
112  if(
113  va_arg_type.is_not_nil() &&
114  !find_symbols(kind, static_cast<const typet &>(va_arg_type), op, bindings))
115  {
116  return false;
117  }
118 
119  return true;
120 }
121 
122 static bool find_symbols(
123  symbol_kindt kind,
124  const typet &src,
125  std::function<bool(const symbol_exprt &)> op,
126  std::unordered_set<irep_idt> &bindings)
127 {
128  if(kind != symbol_kindt::F_TYPE_NON_PTR || src.id() != ID_pointer)
129  {
130  if(
131  src.has_subtype() &&
132  !find_symbols(kind, to_type_with_subtype(src).subtype(), op, bindings))
133  {
134  return false;
135  }
136 
137  for(const typet &subtype : to_type_with_subtypes(src).subtypes())
138  {
139  if(!find_symbols(kind, subtype, op, bindings))
140  return false;
141  }
142 
143  if(
145  kind == symbol_kindt::F_ALL)
146  {
147  const irep_idt &typedef_name = src.get(ID_C_typedef);
148  if(!typedef_name.empty() && !op(symbol_exprt{typedef_name, typet{}}))
149  return false;
150  }
151  }
152 
153  if(src.id()==ID_struct ||
154  src.id()==ID_union)
155  {
156  const struct_union_typet &struct_union_type=to_struct_union_type(src);
157 
158  for(const auto &c : struct_union_type.components())
159  {
160  if(!find_symbols(kind, c, op, bindings))
161  return false;
162  }
163  }
164  else if(src.id()==ID_code)
165  {
166  const code_typet &code_type=to_code_type(src);
167  if(!find_symbols(kind, code_type.return_type(), op, bindings))
168  return false;
169 
170  for(const auto &p : code_type.parameters())
171  {
172  if(!find_symbols(kind, p, op, bindings))
173  return false;
174  }
175  }
176  else if(src.id()==ID_array)
177  {
178  // do the size -- the subtype is already done
179  if(!find_symbols(kind, to_array_type(src).size(), op, bindings))
180  return false;
181  }
182  else if(
184  kind == symbol_kindt::F_ALL)
185  {
186  if(src.id() == ID_c_enum_tag)
187  {
189  return false;
190  }
191  else if(src.id() == ID_struct_tag)
192  {
194  return false;
195  }
196  else if(src.id() == ID_union_tag)
197  {
199  return false;
200  }
201  }
202 
203  return true;
204 }
205 
206 static bool find_symbols(
207  symbol_kindt kind,
208  const typet &type,
209  std::function<bool(const symbol_exprt &)> op)
210 {
211  std::unordered_set<irep_idt> bindings;
212  return find_symbols(kind, type, op, bindings);
213 }
214 
215 static bool find_symbols(
216  symbol_kindt kind,
217  const exprt &src,
218  std::function<bool(const symbol_exprt &)> op)
219 {
220  std::unordered_set<irep_idt> bindings;
221  return find_symbols(kind, src, op, bindings);
222 }
223 
224 void find_symbols(const exprt &src, std::set<symbol_exprt> &dest)
225 {
226  find_symbols(symbol_kindt::F_EXPR, src, [&dest](const symbol_exprt &e) {
227  dest.insert(e);
228  return true;
229  });
230 }
231 
233  const exprt &src,
234  const irep_idt &identifier,
235  bool include_bound_symbols)
236 {
237  return !find_symbols(
238  include_bound_symbols ? symbol_kindt::F_EXPR : symbol_kindt::F_EXPR_FREE,
239  src,
240  [&identifier](const symbol_exprt &e) {
241  return e.get_identifier() != identifier;
242  });
243 }
244 
246 {
247  find_symbols(symbol_kindt::F_TYPE, src, [&dest](const symbol_exprt &e) {
248  dest.insert(e.get_identifier());
249  return true;
250  });
251 }
252 
254 {
255  find_symbols(symbol_kindt::F_TYPE, src, [&dest](const symbol_exprt &e) {
256  dest.insert(e.get_identifier());
257  return true;
258  });
259 }
260 
262  const exprt &src,
263  find_symbols_sett &dest)
264 {
265  find_symbols(
266  symbol_kindt::F_TYPE_NON_PTR, src, [&dest](const symbol_exprt &e) {
267  dest.insert(e.get_identifier());
268  return true;
269  });
270 }
271 
273  const typet &src,
274  find_symbols_sett &dest)
275 {
276  find_symbols(
277  symbol_kindt::F_TYPE_NON_PTR, src, [&dest](const symbol_exprt &e) {
278  dest.insert(e.get_identifier());
279  return true;
280  });
281 }
282 
284 {
285  find_symbols(symbol_kindt::F_ALL, src, [&dest](const symbol_exprt &e) {
286  dest.insert(e.get_identifier());
287  return true;
288  });
289 }
290 
292 {
293  find_symbols(symbol_kindt::F_ALL, src, [&dest](const symbol_exprt &e) {
294  dest.insert(e.get_identifier());
295  return true;
296  });
297 }
298 
299 void find_symbols(const exprt &src, find_symbols_sett &dest)
300 {
301  find_symbols(symbol_kindt::F_EXPR, src, [&dest](const symbol_exprt &e) {
302  dest.insert(e.get_identifier());
303  return true;
304  });
305 }
to_union_tag_type
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition: c_types.h:202
tag_typet::get_identifier
const irep_idt & get_identifier() const
Definition: std_types.h:410
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
find_symbols
static bool find_symbols(symbol_kindt, const typet &, std::function< bool(const symbol_exprt &)>, std::unordered_set< irep_idt > &bindings)
Definition: find_symbols.cpp:122
find_type_and_expr_symbols
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest)
Find identifiers of the sub expressions with id ID_symbol, considering both free and bound variables,...
Definition: find_symbols.cpp:283
to_struct_union_type
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition: std_types.h:214
typet
The type of an expression, extends irept.
Definition: type.h:28
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
typet::has_subtype
bool has_subtype() const
Definition: type.h:82
struct_union_typet
Base type for structs and unions.
Definition: std_types.h:61
find_non_pointer_type_symbols
void find_non_pointer_type_symbols(const exprt &src, find_symbols_sett &dest)
Collect type tags contained in src when the expression of such a type is not a pointer,...
Definition: find_symbols.cpp:261
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
to_type_with_subtypes
const type_with_subtypest & to_type_with_subtypes(const typet &type)
Definition: type.h:237
exprt
Base class for all expressions.
Definition: expr.h:55
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
symbol_kindt
symbol_kindt
Kinds of symbols to be considered by find_symbols.
Definition: find_symbols.cpp:17
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
find_symbols.h
symbol_kindt::F_EXPR_FREE
@ F_EXPR_FREE
Symbol expressions, but excluding bound variables.
to_c_enum_tag_type
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition: c_types.h:344
forall_operands
#define forall_operands(it, expr)
Definition: expr.h:20
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
to_let_expr
const let_exprt & to_let_expr(const exprt &expr)
Cast an exprt to a let_exprt.
Definition: std_expr.h:3266
find_type_symbols
void find_type_symbols(const exprt &src, find_symbols_sett &dest)
Collect all type tags contained in src and add them to dest.
Definition: find_symbols.cpp:245
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
code_typet
Base type of functions.
Definition: std_types.h:538
irept::id
const irep_idt & id() const
Definition: irep.h:396
to_struct_tag_type
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition: std_types.h:474
range.h
dstringt::empty
bool empty() const
Definition: dstring.h:88
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:655
expr_iterator.h
find_symbols_sett
std::unordered_set< irep_idt > find_symbols_sett
Definition: find_symbols.h:21
has_symbol_expr
bool has_symbol_expr(const exprt &src, const irep_idt &identifier, bool include_bound_symbols)
Returns true if one of the symbol expressions in src has identifier identifier; if include_bound_symb...
Definition: find_symbols.cpp:232
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:359
symbol_kindt::F_TYPE_NON_PTR
@ F_TYPE_NON_PTR
Struct, union, or enum tag symbols when the expression using them is not a pointer.
to_binding_expr
const binding_exprt & to_binding_expr(const exprt &expr)
Cast an exprt to a binding_exprt.
Definition: std_expr.h:3114
symbol_kindt::F_ALL
@ F_ALL
All of the above.
std_expr.h
c_types.h
symbol_kindt::F_EXPR
@ F_EXPR
Symbol expressions.
symbol_kindt::F_TYPE
@ F_TYPE
Struct, union, or enum tag symbols.