CBMC
goto_clean_expr.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Program Transformation
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "goto_convert_class.h"
13 
14 #include <util/expr_util.h>
15 #include <util/fresh_symbol.h>
16 #include <util/pointer_expr.h>
17 #include <util/std_expr.h>
18 #include <util/symbol.h>
19 
21  const exprt &expr,
22  goto_programt &dest,
23  const irep_idt &mode)
24 {
25  const source_locationt source_location=expr.find_source_location();
26 
27  symbolt &new_symbol = get_fresh_aux_symbol(
28  expr.type(),
30  "literal",
31  source_location,
32  mode,
33  symbol_table);
35  new_symbol.value=expr;
36 
37  // The value might depend on a variable, thus
38  // generate code for this.
39 
40  symbol_exprt result=new_symbol.symbol_expr();
41  result.add_source_location()=source_location;
42 
43  // The lifetime of compound literals is really that of
44  // the block they are in.
45  if(!new_symbol.is_static_lifetime)
46  copy(code_declt(result), DECL, dest);
47 
48  code_assignt code_assign(result, expr);
49  code_assign.add_source_location()=source_location;
50  convert(code_assign, dest, mode);
51 
52  // now create a 'dead' instruction
53  if(!new_symbol.is_static_lifetime)
54  {
55  code_deadt code_dead(result);
56  targets.destructor_stack.add(std::move(code_dead));
57  }
58 
59  return result;
60 }
61 
68 {
69  if(
70  expr.id() == ID_side_effect || expr.id() == ID_compound_literal ||
71  expr.id() == ID_comma)
72  {
73  return true;
74  }
75 
76  // We can't flatten quantified expressions by introducing new literals for
77  // conditional expressions. This is because the body of the quantified
78  // may refer to bound variables, which are not visible outside the scope
79  // of the quantifier.
80  //
81  // For example, the following transformation would not be valid:
82  //
83  // forall (i : int) (i == 0 || i > 10)
84  //
85  // transforming to
86  //
87  // g1 = (i == 0)
88  // g2 = (i > 10)
89  // forall (i : int) (g1 || g2)
90  if(expr.id()==ID_forall || expr.id()==ID_exists)
91  return false;
92 
93  forall_operands(it, expr)
94  if(needs_cleaning(*it))
95  return true;
96 
97  return false;
98 }
99 
102 {
103  PRECONDITION(
104  expr.id() == ID_and || expr.id() == ID_or || expr.id() == ID_implies);
106  expr.is_boolean(),
107  expr.find_source_location(),
108  "'",
109  expr.id(),
110  "' must be Boolean, but got ",
112 
113  // re-write "a ==> b" into a?b:1
114  if(auto implies = expr_try_dynamic_cast<implies_exprt>(expr))
115  {
116  expr = if_exprt{std::move(implies->lhs()),
117  std::move(implies->rhs()),
118  true_exprt{},
119  bool_typet{}};
120  return;
121  }
122 
123  // re-write "a && b" into nested a?b:0
124  // re-write "a || b" into nested a?1:b
125 
126  exprt tmp;
127 
128  if(expr.id()==ID_and)
129  tmp=true_exprt();
130  else // ID_or
131  tmp=false_exprt();
132 
133  exprt::operandst &ops=expr.operands();
134 
135  // start with last one
136  for(exprt::operandst::reverse_iterator
137  it=ops.rbegin();
138  it!=ops.rend();
139  ++it)
140  {
141  exprt &op=*it;
142 
144  op.is_boolean(),
145  "boolean operators must have only boolean operands",
146  expr.find_source_location());
147 
148  if(expr.id()==ID_and)
149  {
150  if_exprt if_e(op, tmp, false_exprt());
151  tmp.swap(if_e);
152  continue;
153  }
154  if(expr.id() == ID_or)
155  {
156  if_exprt if_e(op, true_exprt(), tmp);
157  tmp.swap(if_e);
158  continue;
159  }
160  UNREACHABLE;
161  }
162 
163  expr.swap(tmp);
164 }
165 
167  exprt &expr,
168  goto_programt &dest,
169  const irep_idt &mode,
170  bool result_is_used)
171 {
172  // this cleans:
173  // && || ==> ?: comma (control-dependency)
174  // function calls
175  // object constructors like arrays, string constants, structs
176  // ++ -- (pre and post)
177  // compound assignments
178  // compound literals
179 
180  if(!needs_cleaning(expr))
181  return;
182 
183  if(expr.id() == ID_and || expr.id() == ID_or || expr.id() == ID_implies)
184  {
185  // rewrite into ?:
186  rewrite_boolean(expr);
187 
188  // recursive call
189  clean_expr(expr, dest, mode, result_is_used);
190  return;
191  }
192  else if(expr.id()==ID_if)
193  {
194  // first clean condition
195  clean_expr(to_if_expr(expr).cond(), dest, mode, true);
196 
197  // possibly done now
198  if(!needs_cleaning(to_if_expr(expr).true_case()) &&
199  !needs_cleaning(to_if_expr(expr).false_case()))
200  return;
201 
202  // copy expression
203  if_exprt if_expr=to_if_expr(expr);
204 
206  if_expr.cond().is_boolean(),
207  "condition for an 'if' must be boolean",
208  if_expr.find_source_location());
209 
210  const source_locationt source_location=expr.find_source_location();
211 
212  #if 0
213  // We do some constant-folding here, to mimic
214  // what typical compilers do.
215  {
216  exprt tmp_cond=if_expr.cond();
217  simplify(tmp_cond, ns);
218  if(tmp_cond.is_true())
219  {
220  clean_expr(if_expr.true_case(), dest, result_is_used);
221  expr=if_expr.true_case();
222  return;
223  }
224  else if(tmp_cond.is_false())
225  {
226  clean_expr(if_expr.false_case(), dest, result_is_used);
227  expr=if_expr.false_case();
228  return;
229  }
230  }
231  #endif
232 
233  goto_programt tmp_true;
234  clean_expr(if_expr.true_case(), tmp_true, mode, result_is_used);
235 
236  goto_programt tmp_false;
237  clean_expr(if_expr.false_case(), tmp_false, mode, result_is_used);
238 
239  if(result_is_used)
240  {
241  symbolt &new_symbol =
242  new_tmp_symbol(expr.type(), "if_expr", dest, source_location, mode);
243 
244  code_assignt assignment_true;
245  assignment_true.lhs()=new_symbol.symbol_expr();
246  assignment_true.rhs()=if_expr.true_case();
247  assignment_true.add_source_location()=source_location;
248  convert(assignment_true, tmp_true, mode);
249 
250  code_assignt assignment_false;
251  assignment_false.lhs()=new_symbol.symbol_expr();
252  assignment_false.rhs()=if_expr.false_case();
253  assignment_false.add_source_location()=source_location;
254  convert(assignment_false, tmp_false, mode);
255 
256  // overwrites expr
257  expr=new_symbol.symbol_expr();
258  }
259  else
260  {
261  // preserve the expressions for possible later checks
262  if(if_expr.true_case().is_not_nil())
263  {
264  // add a (void) type cast so that is_skip catches it in case the
265  // expression is just a constant
266  code_expressiont code_expression(
267  typecast_exprt(if_expr.true_case(), empty_typet()));
268  convert(code_expression, tmp_true, mode);
269  }
270 
271  if(if_expr.false_case().is_not_nil())
272  {
273  // add a (void) type cast so that is_skip catches it in case the
274  // expression is just a constant
275  code_expressiont code_expression(
276  typecast_exprt(if_expr.false_case(), empty_typet()));
277  convert(code_expression, tmp_false, mode);
278  }
279 
280  expr=nil_exprt();
281  }
282 
283  // generate guard for argument side-effects
285  if_expr.cond(), tmp_true, tmp_false, source_location, dest, mode);
286 
287  return;
288  }
289  else if(expr.id()==ID_comma)
290  {
291  if(result_is_used)
292  {
293  exprt result;
294 
295  Forall_operands(it, expr)
296  {
297  bool last=(it==--expr.operands().end());
298 
299  // special treatment for last one
300  if(last)
301  {
302  result.swap(*it);
303  clean_expr(result, dest, mode, true);
304  }
305  else
306  {
307  clean_expr(*it, dest, mode, false);
308 
309  // remember these for later checks
310  if(it->is_not_nil())
311  convert(code_expressiont(*it), dest, mode);
312  }
313  }
314 
315  expr.swap(result);
316  }
317  else // result not used
318  {
319  Forall_operands(it, expr)
320  {
321  clean_expr(*it, dest, mode, false);
322 
323  // remember as expression statement for later checks
324  if(it->is_not_nil())
325  convert(code_expressiont(*it), dest, mode);
326  }
327 
328  expr=nil_exprt();
329  }
330 
331  return;
332  }
333  else if(expr.id()==ID_typecast)
334  {
335  typecast_exprt &typecast = to_typecast_expr(expr);
336 
337  // preserve 'result_is_used'
338  clean_expr(typecast.op(), dest, mode, result_is_used);
339 
340  if(typecast.op().is_nil())
341  expr.make_nil();
342 
343  return;
344  }
345  else if(expr.id()==ID_side_effect)
346  {
347  // some of the side-effects need special treatment!
348  const irep_idt statement=to_side_effect_expr(expr).get_statement();
349 
350  if(statement==ID_gcc_conditional_expression)
351  {
352  // need to do separately
353  remove_gcc_conditional_expression(expr, dest, mode);
354  return;
355  }
356  else if(statement==ID_statement_expression)
357  {
358  // need to do separately to prevent that
359  // the operands of expr get 'cleaned'
361  to_side_effect_expr(expr), dest, mode, result_is_used);
362  return;
363  }
364  else if(statement==ID_assign)
365  {
366  // we do a special treatment for x=f(...)
367  INVARIANT(
368  expr.operands().size() == 2,
369  "side-effect assignment expressions must have two operands");
370 
371  auto &side_effect_assign = to_side_effect_expr_assign(expr);
372 
373  if(
374  side_effect_assign.rhs().id() == ID_side_effect &&
375  to_side_effect_expr(side_effect_assign.rhs()).get_statement() ==
376  ID_function_call)
377  {
378  clean_expr(side_effect_assign.lhs(), dest, mode);
379  exprt lhs = side_effect_assign.lhs();
380 
381  const bool must_use_rhs = assignment_lhs_needs_temporary(lhs);
382  if(must_use_rhs)
383  {
385  to_side_effect_expr_function_call(side_effect_assign.rhs()),
386  dest,
387  mode,
388  true);
389  }
390 
391  // turn into code
392  exprt new_lhs = skip_typecast(lhs);
394  side_effect_assign.rhs(), new_lhs.type());
395  code_assignt assignment(std::move(new_lhs), std::move(new_rhs));
396  assignment.add_source_location()=expr.source_location();
397  convert_assign(assignment, dest, mode);
398 
399  if(result_is_used)
400  expr = must_use_rhs ? side_effect_assign.rhs() : lhs;
401  else
402  expr.make_nil();
403  return;
404  }
405  }
406  }
407  else if(expr.id()==ID_forall || expr.id()==ID_exists)
408  {
410  !has_subexpr(expr, ID_side_effect),
411  "the front-end should check quantified expressions for side-effects");
412  }
413  else if(expr.id()==ID_address_of)
414  {
415  address_of_exprt &addr = to_address_of_expr(expr);
416  clean_expr_address_of(addr.object(), dest, mode);
417  return;
418  }
419 
420  // TODO: evaluation order
421 
422  Forall_operands(it, expr)
423  clean_expr(*it, dest, mode);
424 
425  if(expr.id()==ID_side_effect)
426  {
428  to_side_effect_expr(expr), dest, mode, result_is_used, false);
429  }
430  else if(expr.id()==ID_compound_literal)
431  {
432  // This is simply replaced by the literal
434  expr.operands().size() == 1, "ID_compound_literal has a single operand");
435  expr = to_unary_expr(expr).op();
436  }
437 }
438 
440  exprt &expr,
441  goto_programt &dest,
442  const irep_idt &mode)
443 {
444  // The address of object constructors can be taken,
445  // which is re-written into the address of a variable.
446 
447  if(expr.id()==ID_compound_literal)
448  {
450  expr.operands().size() == 1, "ID_compound_literal has a single operand");
451  clean_expr(to_unary_expr(expr).op(), dest, mode);
452  expr = make_compound_literal(to_unary_expr(expr).op(), dest, mode);
453  }
454  else if(expr.id()==ID_string_constant)
455  {
456  // Leave for now, but long-term these might become static symbols.
457  // LLVM appears to do precisely that.
458  }
459  else if(expr.id()==ID_index)
460  {
461  index_exprt &index_expr = to_index_expr(expr);
462  clean_expr_address_of(index_expr.array(), dest, mode);
463  clean_expr(index_expr.index(), dest, mode);
464  }
465  else if(expr.id()==ID_dereference)
466  {
467  dereference_exprt &deref_expr = to_dereference_expr(expr);
468  clean_expr(deref_expr.pointer(), dest, mode);
469  }
470  else if(expr.id()==ID_comma)
471  {
472  // Yes, one can take the address of a comma expression.
473  // Treatment is similar to clean_expr() above.
474 
475  exprt result;
476 
477  Forall_operands(it, expr)
478  {
479  bool last=(it==--expr.operands().end());
480 
481  // special treatment for last one
482  if(last)
483  result.swap(*it);
484  else
485  {
486  clean_expr(*it, dest, mode, false);
487 
488  // get any side-effects
489  if(it->is_not_nil())
490  convert(code_expressiont(*it), dest, mode);
491  }
492  }
493 
494  expr.swap(result);
495 
496  // do again
497  clean_expr_address_of(expr, dest, mode);
498  }
499  else if(expr.id() == ID_side_effect)
500  {
501  remove_side_effect(to_side_effect_expr(expr), dest, mode, true, true);
502  }
503  else
504  Forall_operands(it, expr)
505  clean_expr_address_of(*it, dest, mode);
506 }
507 
509  exprt &expr,
510  goto_programt &dest,
511  const irep_idt &mode)
512 {
513  {
514  auto &binary_expr = to_binary_expr(expr);
515 
516  // first remove side-effects from condition
517  clean_expr(to_binary_expr(expr).op0(), dest, mode);
518 
519  // now we can copy op0 safely
520  if_exprt if_expr(
521  typecast_exprt::conditional_cast(binary_expr.op0(), bool_typet()),
522  binary_expr.op0(),
523  binary_expr.op1(),
524  expr.type());
525  if_expr.add_source_location() = expr.source_location();
526 
527  expr.swap(if_expr);
528  }
529 
530  // there might still be junk in expr.op2()
531  clean_expr(expr, dest, mode);
532 }
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
to_unary_expr
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:361
goto_convertt::needs_cleaning
static bool needs_cleaning(const exprt &expr)
Returns 'true' for expressions that may change the program state.
Definition: goto_clean_expr.cpp:67
skip_typecast
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Definition: expr_util.cpp:217
to_side_effect_expr_function_call
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
Definition: std_code.h:1739
has_subexpr
bool has_subexpr(const exprt &expr, const std::function< bool(const exprt &)> &pred)
returns true if the expression has a subexpression that satisfies pred
Definition: expr_util.cpp:139
Forall_operands
#define Forall_operands(it, expr)
Definition: expr.h:27
goto_convertt::ns
namespacet ns
Definition: goto_convert_class.h:52
address_of_exprt::object
exprt & object()
Definition: pointer_expr.h:380
lifetimet::AUTOMATIC_LOCAL
@ AUTOMATIC_LOCAL
Allocate local objects with automatic lifetime.
goto_convertt::convert
void convert(const codet &code, goto_programt &dest, const irep_idt &mode)
converts 'code' and appends the result to 'dest'
Definition: goto_convert.cpp:430
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
goto_convertt::copy
void copy(const codet &code, goto_program_instruction_typet type, goto_programt &dest)
Definition: goto_convert.cpp:300
irept::make_nil
void make_nil()
Definition: irep.h:454
code_assignt::rhs
exprt & rhs()
Definition: goto_instruction_code.h:48
fresh_symbol.h
goto_convertt::clean_expr
void clean_expr(exprt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used=true)
Definition: goto_clean_expr.cpp:166
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
to_if_expr
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2403
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
goto_convertt::remove_gcc_conditional_expression
void remove_gcc_conditional_expression(exprt &expr, goto_programt &dest, const irep_idt &mode)
Definition: goto_clean_expr.cpp:508
if_exprt
The trinary if-then-else operator.
Definition: std_expr.h:2322
goto_convertt::tmp_symbol_prefix
std::string tmp_symbol_prefix
Definition: goto_convert_class.h:53
code_declt
A goto_instruction_codet representing the declaration of a local variable.
Definition: goto_instruction_code.h:204
goto_convert_class.h
goto_convertt::generate_ifthenelse
void generate_ifthenelse(const exprt &cond, goto_programt &true_case, goto_programt &false_case, const source_locationt &, goto_programt &dest, const irep_idt &mode)
if(guard) true_case; else false_case;
Definition: goto_convert.cpp:1509
goto_convertt::remove_function_call
void remove_function_call(side_effect_expr_function_callt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used)
Definition: goto_convert_side_effect.cpp:354
exprt
Base class for all expressions.
Definition: expr.h:55
exprt::op0
exprt & op0()
Definition: expr.h:125
bool_typet
The Boolean type.
Definition: std_types.h:35
goto_convertt::clean_expr_address_of
void clean_expr_address_of(exprt &expr, goto_programt &dest, const irep_idt &mode)
Definition: goto_clean_expr.cpp:439
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
to_side_effect_expr
side_effect_exprt & to_side_effect_expr(exprt &expr)
Definition: std_code.h:1506
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
if_exprt::false_case
exprt & false_case()
Definition: std_expr.h:2360
goto_convertt::new_tmp_symbol
symbolt & new_tmp_symbol(const typet &type, const std::string &suffix, goto_programt &dest, const source_locationt &, const irep_idt &mode)
Definition: goto_convert.cpp:1861
exprt::is_false
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:43
to_binary_expr
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:660
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
goto_convertt::targets
struct goto_convertt::targetst targets
destructor_treet::add
void add(const codet &destructor)
Adds a destructor to the current stack, attaching itself to the current node.
Definition: destructor_tree.cpp:11
messaget::result
mstreamt & result() const
Definition: message.h:409
empty_typet
The empty type.
Definition: std_types.h:50
DATA_INVARIANT_WITH_DIAGNOSTICS
#define DATA_INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Definition: invariant.h:511
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
forall_operands
#define forall_operands(it, expr)
Definition: expr.h:20
goto_convertt::rewrite_boolean
void rewrite_boolean(exprt &dest)
re-write boolean operators into ?:
Definition: goto_clean_expr.cpp:101
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
exprt::find_source_location
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:165
nil_exprt
The NIL expression.
Definition: std_expr.h:3025
dereference_exprt::pointer
exprt & pointer()
Definition: pointer_expr.h:673
goto_convertt::remove_statement_expression
void remove_statement_expression(side_effect_exprt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used)
Definition: goto_convert_side_effect.cpp:532
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
pointer_expr.h
code_assignt::lhs
exprt & lhs()
Definition: goto_instruction_code.h:43
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
exprt::op1
exprt & op1()
Definition: expr.h:128
goto_convertt::make_compound_literal
symbol_exprt make_compound_literal(const exprt &expr, goto_programt &dest, const irep_idt &mode)
Definition: goto_clean_expr.cpp:20
index_exprt::index
exprt & index()
Definition: std_expr.h:1450
index_exprt::array
exprt & array()
Definition: std_expr.h:1440
irept::swap
void swap(irept &irep)
Definition: irep.h:442
symbol.h
Symbol table entry.
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
false_exprt
The Boolean constant false.
Definition: std_expr.h:3016
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
code_deadt
A goto_instruction_codet representing the removal of a local variable going out of scope.
Definition: goto_instruction_code.h:131
goto_convertt::convert_assign
void convert_assign(const code_assignt &code, goto_programt &dest, const irep_idt &mode)
Definition: goto_convert.cpp:682
to_side_effect_expr_assign
side_effect_expr_assignt & to_side_effect_expr_assign(exprt &expr)
Definition: std_code.h:1618
side_effect_exprt::get_statement
const irep_idt & get_statement() const
Definition: std_code.h:1472
source_locationt
Definition: source_location.h:18
irep_pretty_diagnosticst
Definition: irep.h:502
expr_util.h
Deprecated expression utility functions.
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
if_exprt::true_case
exprt & true_case()
Definition: std_expr.h:2350
DECL
@ DECL
Definition: goto_program.h:47
goto_convertt::targetst::destructor_stack
destructor_treet destructor_stack
Definition: goto_convert_class.h:391
symbolt
Symbol table entry.
Definition: symbol.h:27
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2051
PRECONDITION_WITH_DIAGNOSTICS
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
Definition: invariant.h:464
if_exprt::cond
exprt & cond()
Definition: std_expr.h:2340
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
goto_convertt::remove_side_effect
void remove_side_effect(side_effect_exprt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used, bool address_taken)
Definition: goto_convert_side_effect.cpp:673
goto_convertt::symbol_table
symbol_table_baset & symbol_table
Definition: goto_convert_class.h:51
goto_convertt::assignment_lhs_needs_temporary
static bool assignment_lhs_needs_temporary(const exprt &lhs)
Definition: goto_convert_class.h:96
to_address_of_expr
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:408
exprt::operands
operandst & operands()
Definition: expr.h:94
index_exprt
Array index operator.
Definition: std_expr.h:1409
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
code_assignt
A goto_instruction_codet representing an assignment in the program.
Definition: goto_instruction_code.h:22
true_exprt
The Boolean constant true.
Definition: std_expr.h:3007
exprt::is_boolean
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition: expr.cpp:52
std_expr.h
goto_convertt::lifetime
lifetimet lifetime
Definition: goto_convert_class.h:54
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
get_fresh_aux_symbol
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Definition: fresh_symbol.cpp:32
validation_modet::INVARIANT
@ INVARIANT
code_expressiont
codet representation of an expression statement.
Definition: std_code.h:1393