CBMC
goto_convert_side_effect.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/arith_tools.h>
15 #include <util/bitvector_expr.h>
16 #include <util/c_types.h>
17 #include <util/expr_util.h>
18 #include <util/fresh_symbol.h>
20 #include <util/std_expr.h>
21 #include <util/symbol.h>
22 
23 #include <ansi-c/c_expr.h>
24 
26 {
27  forall_operands(it, expr)
28  if(has_function_call(*it))
29  return true;
30 
31  if(expr.id()==ID_side_effect &&
32  expr.get(ID_statement)==ID_function_call)
33  return true;
34 
35  return false;
36 }
37 
39  side_effect_exprt &expr,
40  goto_programt &dest,
41  bool result_is_used,
42  bool address_taken,
43  const irep_idt &mode)
44 {
45  const irep_idt statement=expr.get_statement();
46 
47  optionalt<exprt> replacement_expr_opt;
48 
49  if(statement==ID_assign)
50  {
51  auto &old_assignment = to_side_effect_expr_assign(expr);
52 
53  if(
54  result_is_used && !address_taken &&
55  assignment_lhs_needs_temporary(old_assignment.lhs()))
56  {
57  if(!old_assignment.rhs().is_constant())
58  make_temp_symbol(old_assignment.rhs(), "assign", dest, mode);
59 
60  replacement_expr_opt = old_assignment.rhs();
61  }
62 
63  exprt new_lhs = skip_typecast(old_assignment.lhs());
64  exprt new_rhs =
65  typecast_exprt::conditional_cast(old_assignment.rhs(), new_lhs.type());
66  code_assignt new_assignment(std::move(new_lhs), std::move(new_rhs));
67  new_assignment.add_source_location() = expr.source_location();
68 
69  convert_assign(new_assignment, dest, mode);
70  }
71  else if(statement==ID_assign_plus ||
72  statement==ID_assign_minus ||
73  statement==ID_assign_mult ||
74  statement==ID_assign_div ||
75  statement==ID_assign_mod ||
76  statement==ID_assign_shl ||
77  statement==ID_assign_ashr ||
78  statement==ID_assign_lshr ||
79  statement==ID_assign_bitand ||
80  statement==ID_assign_bitxor ||
81  statement==ID_assign_bitor)
82  {
84  expr.operands().size() == 2,
85  id2string(statement) + " expects two arguments",
86  expr.find_source_location());
87 
88  irep_idt new_id;
89 
90  if(statement==ID_assign_plus)
91  new_id=ID_plus;
92  else if(statement==ID_assign_minus)
93  new_id=ID_minus;
94  else if(statement==ID_assign_mult)
95  new_id=ID_mult;
96  else if(statement==ID_assign_div)
97  new_id=ID_div;
98  else if(statement==ID_assign_mod)
99  new_id=ID_mod;
100  else if(statement==ID_assign_shl)
101  new_id=ID_shl;
102  else if(statement==ID_assign_ashr)
103  new_id=ID_ashr;
104  else if(statement==ID_assign_lshr)
105  new_id=ID_lshr;
106  else if(statement==ID_assign_bitand)
107  new_id=ID_bitand;
108  else if(statement==ID_assign_bitxor)
109  new_id=ID_bitxor;
110  else if(statement==ID_assign_bitor)
111  new_id=ID_bitor;
112  else
113  {
114  UNREACHABLE;
115  }
116 
117  const binary_exprt &binary_expr = to_binary_expr(expr);
118  const typet &op0_type = binary_expr.op0().type();
119 
120  PRECONDITION(
121  op0_type.id() != ID_c_enum_tag && op0_type.id() != ID_c_enum &&
122  op0_type.id() != ID_c_bool && op0_type.id() != ID_bool);
123 
124  exprt rhs = binary_exprt{binary_expr.op0(), new_id, binary_expr.op1()};
125  rhs.add_source_location() = expr.source_location();
126 
127  if(
128  result_is_used && !address_taken &&
129  assignment_lhs_needs_temporary(binary_expr.op0()))
130  {
131  make_temp_symbol(rhs, "assign", dest, mode);
132  replacement_expr_opt = rhs;
133  }
134 
135  exprt new_lhs = skip_typecast(binary_expr.op0());
136  rhs = typecast_exprt::conditional_cast(rhs, new_lhs.type());
137  rhs.add_source_location() = expr.source_location();
138  code_assignt assignment(new_lhs, rhs);
139  assignment.add_source_location()=expr.source_location();
140 
141  convert(assignment, dest, mode);
142  }
143  else
144  UNREACHABLE;
145 
146  // revert assignment in the expression to its LHS
147  if(replacement_expr_opt.has_value())
148  {
149  exprt new_lhs =
150  typecast_exprt::conditional_cast(*replacement_expr_opt, expr.type());
151  expr.swap(new_lhs);
152  }
153  else if(result_is_used)
154  {
155  exprt lhs = to_binary_expr(expr).op0();
156  // assign_* statements can have an lhs operand with a different type than
157  // that of the overall expression, because of integer promotion (which may
158  // have introduced casts to the lhs).
159  if(expr.type() != lhs.type())
160  {
161  // Skip over those type casts, but also
162  // make sure the resulting expression has the same type as before.
164  lhs.id() == ID_typecast,
165  id2string(expr.id()) +
166  " expression with different operand type expected to have a "
167  "typecast");
169  to_typecast_expr(lhs).op().type() == expr.type(),
170  id2string(expr.id()) + " type mismatch in lhs operand");
171  lhs = to_typecast_expr(lhs).op();
172  }
173  expr.swap(lhs);
174  }
175  else
176  expr.make_nil();
177 }
178 
180  side_effect_exprt &expr,
181  goto_programt &dest,
182  bool result_is_used,
183  bool address_taken,
184  const irep_idt &mode)
185 {
187  expr.operands().size() == 1,
188  "preincrement/predecrement must have one operand",
189  expr.find_source_location());
190 
191  const irep_idt statement=expr.get_statement();
192 
194  statement == ID_preincrement || statement == ID_predecrement,
195  "expects preincrement or predecrement");
196 
197  const auto &op = to_unary_expr(expr).op();
198  const typet &op_type = op.type();
199 
200  PRECONDITION(
201  op_type.id() != ID_c_enum_tag && op_type.id() != ID_c_enum &&
202  op_type.id() != ID_c_bool && op_type.id() != ID_bool);
203 
204  typet constant_type;
205 
206  if(op_type.id() == ID_pointer)
207  constant_type = c_index_type();
208  else if(is_number(op_type))
209  constant_type = op_type;
210  else
211  {
212  UNREACHABLE;
213  }
214 
215  exprt constant;
216 
217  if(constant_type.id() == ID_complex)
218  {
219  exprt real = from_integer(1, to_complex_type(constant_type).subtype());
220  exprt imag = from_integer(0, to_complex_type(constant_type).subtype());
221  constant = complex_exprt(real, imag, to_complex_type(constant_type));
222  }
223  else
224  constant = from_integer(1, constant_type);
225 
226  exprt rhs = binary_exprt{
227  op, statement == ID_preincrement ? ID_plus : ID_minus, std::move(constant)};
228  rhs.add_source_location() = expr.source_location();
229 
230  // Is there a typecast, e.g., for _Bool? If so, transform
231  // t1(op : t2) := op+1 --> op := t2(op+1)
232  exprt lhs;
233  if(op.id() == ID_typecast)
234  {
235  lhs = to_typecast_expr(op).op();
236  rhs = typecast_exprt(rhs, lhs.type());
237  }
238  else
239  {
240  lhs = op;
241  }
242 
243  const bool cannot_use_lhs =
244  result_is_used && !address_taken && assignment_lhs_needs_temporary(lhs);
245  if(cannot_use_lhs)
246  make_temp_symbol(rhs, "pre", dest, mode);
247 
248  code_assignt assignment(lhs, rhs);
249  assignment.add_source_location()=expr.find_source_location();
250 
251  convert(assignment, dest, mode);
252 
253  if(result_is_used)
254  {
255  if(cannot_use_lhs)
256  {
257  auto tmp = typecast_exprt::conditional_cast(rhs, expr.type());
258  expr.swap(tmp);
259  }
260  else
261  {
262  // revert to argument of pre-inc/pre-dec
263  auto tmp = typecast_exprt::conditional_cast(lhs, expr.type());
264  expr.swap(tmp);
265  }
266  }
267  else
268  expr.make_nil();
269 }
270 
272  side_effect_exprt &expr,
273  goto_programt &dest,
274  const irep_idt &mode,
275  bool result_is_used)
276 {
277  goto_programt tmp1, tmp2;
278 
279  // we have ...(op++)...
280 
282  expr.operands().size() == 1,
283  "postincrement/postdecrement must have one operand",
284  expr.find_source_location());
285 
286  const irep_idt statement=expr.get_statement();
287 
289  statement == ID_postincrement || statement == ID_postdecrement,
290  "expects postincrement or postdecrement");
291 
292  const auto &op = to_unary_expr(expr).op();
293  const typet &op_type = op.type();
294 
295  PRECONDITION(
296  op_type.id() != ID_c_enum_tag && op_type.id() != ID_c_enum &&
297  op_type.id() != ID_c_bool && op_type.id() != ID_bool);
298 
299  typet constant_type;
300 
301  if(op_type.id() == ID_pointer)
302  constant_type = c_index_type();
303  else if(is_number(op_type))
304  constant_type = op_type;
305  else
306  {
307  UNREACHABLE;
308  }
309 
310  exprt constant;
311 
312  if(constant_type.id() == ID_complex)
313  {
314  exprt real = from_integer(1, to_complex_type(constant_type).subtype());
315  exprt imag = from_integer(0, to_complex_type(constant_type).subtype());
316  constant = complex_exprt(real, imag, to_complex_type(constant_type));
317  }
318  else
319  constant = from_integer(1, constant_type);
320 
321  binary_exprt rhs{
322  op,
323  statement == ID_postincrement ? ID_plus : ID_minus,
324  std::move(constant)};
325  rhs.add_source_location() = expr.source_location();
326 
327  code_assignt assignment(op, rhs);
328  assignment.add_source_location()=expr.find_source_location();
329 
330  convert(assignment, tmp2, mode);
331 
332  // fix up the expression, if needed
333 
334  if(result_is_used)
335  {
336  exprt tmp = op;
337  std::string suffix = "post";
338  if(auto sym_expr = expr_try_dynamic_cast<symbol_exprt>(tmp))
339  {
340  const irep_idt &base_name = ns.lookup(*sym_expr).base_name;
341  suffix += "_" + id2string(base_name);
342  }
343 
344  make_temp_symbol(tmp, suffix, dest, mode);
345  expr.swap(tmp);
346  }
347  else
348  expr.make_nil();
349 
350  dest.destructive_append(tmp1);
351  dest.destructive_append(tmp2);
352 }
353 
356  goto_programt &dest,
357  const irep_idt &mode,
358  bool result_is_used)
359 {
360  if(!result_is_used)
361  {
362  code_function_callt call(expr.function(), expr.arguments());
363  call.add_source_location()=expr.source_location();
364  convert_function_call(call, dest, mode);
365  expr.make_nil();
366  return;
367  }
368 
369  // get name of function, if available
370  std::string new_base_name = "return_value";
371  irep_idt new_symbol_mode = mode;
372 
373  if(expr.function().id() == ID_symbol)
374  {
375  const irep_idt &identifier =
377  const symbolt &symbol = ns.lookup(identifier);
378 
379  new_base_name+='_';
380  new_base_name+=id2string(symbol.base_name);
381  new_symbol_mode = symbol.mode;
382  }
383 
384  const symbolt &new_symbol = get_fresh_aux_symbol(
385  expr.type(),
387  new_base_name,
388  expr.find_source_location(),
389  new_symbol_mode,
390  symbol_table);
391 
392  {
393  code_frontend_declt decl(new_symbol.symbol_expr());
394  decl.add_source_location()=new_symbol.location;
395  convert_frontend_decl(decl, dest, mode);
396  }
397 
398  {
399  goto_programt tmp_program2;
400  code_function_callt call(
401  new_symbol.symbol_expr(), expr.function(), expr.arguments());
402  call.add_source_location()=new_symbol.location;
403  convert_function_call(call, dest, mode);
404  }
405 
406  static_cast<exprt &>(expr)=new_symbol.symbol_expr();
407 }
408 
410  const exprt &object,
411  exprt &dest)
412 {
413  if(dest.id()=="new_object")
414  dest=object;
415  else
416  Forall_operands(it, dest)
417  replace_new_object(object, *it);
418 }
419 
421  side_effect_exprt &expr,
422  goto_programt &dest,
423  bool result_is_used)
424 {
425  const symbolt &new_symbol = get_fresh_aux_symbol(
426  expr.type(),
428  "new_ptr",
429  expr.find_source_location(),
430  ID_cpp,
431  symbol_table);
432 
433  code_frontend_declt decl(new_symbol.symbol_expr());
434  decl.add_source_location()=new_symbol.location;
435  convert_frontend_decl(decl, dest, ID_cpp);
436 
437  const code_assignt call(new_symbol.symbol_expr(), expr);
438 
439  if(result_is_used)
440  static_cast<exprt &>(expr)=new_symbol.symbol_expr();
441  else
442  expr.make_nil();
443 
444  convert(call, dest, ID_cpp);
445 }
446 
448  side_effect_exprt &expr,
449  goto_programt &dest)
450 {
451  DATA_INVARIANT(expr.operands().size() == 1, "cpp_delete expects one operand");
452 
453  codet tmp(expr.get_statement());
455  tmp.copy_to_operands(to_unary_expr(expr).op());
456  tmp.set(ID_destructor, expr.find(ID_destructor));
457 
458  convert_cpp_delete(tmp, dest);
459 
460  expr.make_nil();
461 }
462 
464  side_effect_exprt &expr,
465  goto_programt &dest,
466  const irep_idt &mode,
467  bool result_is_used)
468 {
469  if(result_is_used)
470  {
471  const symbolt &new_symbol = get_fresh_aux_symbol(
472  expr.type(),
474  "malloc_value",
475  expr.source_location(),
476  mode,
477  symbol_table);
478 
479  code_frontend_declt decl(new_symbol.symbol_expr());
480  decl.add_source_location()=new_symbol.location;
481  convert_frontend_decl(decl, dest, mode);
482 
483  code_assignt call(new_symbol.symbol_expr(), expr);
484  call.add_source_location()=expr.source_location();
485 
486  static_cast<exprt &>(expr)=new_symbol.symbol_expr();
487 
488  convert(call, dest, mode);
489  }
490  else
491  {
492  convert(code_expressiont(std::move(expr)), dest, mode);
493  }
494 }
495 
497  side_effect_exprt &expr,
498  goto_programt &dest)
499 {
500  const irep_idt &mode = expr.get(ID_mode);
502  expr.operands().size() <= 1,
503  "temporary_object takes zero or one operands",
504  expr.find_source_location());
505 
506  symbolt &new_symbol = new_tmp_symbol(
507  expr.type(), "obj", dest, expr.find_source_location(), mode);
508 
509  if(expr.operands().size()==1)
510  {
511  const code_assignt assignment(
512  new_symbol.symbol_expr(), to_unary_expr(expr).op());
513 
514  convert(assignment, dest, mode);
515  }
516 
517  if(expr.find(ID_initializer).is_not_nil())
518  {
520  expr.operands().empty(),
521  "temporary_object takes zero operands",
522  expr.find_source_location());
523  exprt initializer=static_cast<const exprt &>(expr.find(ID_initializer));
524  replace_new_object(new_symbol.symbol_expr(), initializer);
525 
526  convert(to_code(initializer), dest, mode);
527  }
528 
529  static_cast<exprt &>(expr)=new_symbol.symbol_expr();
530 }
531 
533  side_effect_exprt &expr,
534  goto_programt &dest,
535  const irep_idt &mode,
536  bool result_is_used)
537 {
538  // This is a gcc extension of the form ({ ....; expr; })
539  // The value is that of the final expression.
540  // The expression is copied into a temporary before the
541  // scope is destroyed.
542 
544 
545  if(!result_is_used)
546  {
547  convert(code, dest, mode);
548  expr.make_nil();
549  return;
550  }
551 
553  code.get_statement() == ID_block,
554  "statement_expression takes block as operand",
555  code.find_source_location());
556 
558  !code.operands().empty(),
559  "statement_expression takes non-empty block as operand",
560  expr.find_source_location());
561 
562  // get last statement from block, following labels
564 
565  source_locationt source_location=last.find_source_location();
566 
567  symbolt &new_symbol = new_tmp_symbol(
568  expr.type(), "statement_expression", dest, source_location, mode);
569 
570  symbol_exprt tmp_symbol_expr(new_symbol.name, new_symbol.type);
571  tmp_symbol_expr.add_source_location()=source_location;
572 
573  if(last.get(ID_statement)==ID_expression)
574  {
575  // we turn this into an assignment
577  last=code_assignt(tmp_symbol_expr, e);
578  last.add_source_location()=source_location;
579  }
580  else if(last.get(ID_statement)==ID_assign)
581  {
582  exprt e=to_code_assign(last).lhs();
583  code_assignt assignment(tmp_symbol_expr, e);
584  assignment.add_source_location()=source_location;
585  code.operands().push_back(assignment);
586  }
587  else
588  {
589  UNREACHABLE;
590  }
591 
592  {
593  goto_programt tmp;
594  convert(code, tmp, mode);
595  dest.destructive_append(tmp);
596  }
597 
598  static_cast<exprt &>(expr)=tmp_symbol_expr;
599 }
600 
603  goto_programt &dest,
604  bool result_is_used,
605  const irep_idt &mode)
606 {
607  const irep_idt &statement = expr.get_statement();
608  const exprt &lhs = expr.lhs();
609  const exprt &rhs = expr.rhs();
610  const exprt &result = expr.result();
611 
612  if(result.type().id() != ID_pointer)
613  {
614  // result of the arithmetic operation is _not_ used, just evaluate side
615  // effects
616  exprt tmp = result;
617  clean_expr(tmp, dest, mode, false);
618 
619  // the is-there-an-overflow result may be used
620  if(result_is_used)
621  {
622  binary_overflow_exprt overflow_check{
624  statement,
626  overflow_check.add_source_location() = expr.source_location();
627  expr.swap(overflow_check);
628  }
629  else
630  expr.make_nil();
631  }
632  else
633  {
634  const typet &arith_type = to_pointer_type(result.type()).base_type();
635  irep_idt arithmetic_operation =
636  statement == ID_overflow_plus
637  ? ID_plus
638  : statement == ID_overflow_minus
639  ? ID_minus
640  : statement == ID_overflow_mult ? ID_mult : ID_nil;
641  CHECK_RETURN(arithmetic_operation != ID_nil);
642  exprt overflow_with_result = overflow_result_exprt{
643  typecast_exprt::conditional_cast(lhs, arith_type),
644  arithmetic_operation,
645  typecast_exprt::conditional_cast(rhs, arith_type)};
646  overflow_with_result.add_source_location() = expr.source_location();
647 
648  if(result_is_used)
649  make_temp_symbol(overflow_with_result, "overflow_result", dest, mode);
650 
651  const struct_typet::componentst &result_comps =
652  to_struct_type(overflow_with_result.type()).components();
653  CHECK_RETURN(result_comps.size() == 2);
654  code_assignt result_assignment{
657  member_exprt{overflow_with_result, result_comps[0]}, arith_type),
658  expr.source_location()};
659  convert_assign(result_assignment, dest, mode);
660 
661  if(result_is_used)
662  {
663  member_exprt overflow_check{overflow_with_result, result_comps[1]};
664  overflow_check.add_source_location() = expr.source_location();
665 
666  expr.swap(overflow_check);
667  }
668  else
669  expr.make_nil();
670  }
671 }
672 
674  side_effect_exprt &expr,
675  goto_programt &dest,
676  const irep_idt &mode,
677  bool result_is_used,
678  bool address_taken)
679 {
680  const irep_idt &statement=expr.get_statement();
681 
682  if(statement==ID_function_call)
684  to_side_effect_expr_function_call(expr), dest, mode, result_is_used);
685  else if(statement==ID_assign ||
686  statement==ID_assign_plus ||
687  statement==ID_assign_minus ||
688  statement==ID_assign_mult ||
689  statement==ID_assign_div ||
690  statement==ID_assign_bitor ||
691  statement==ID_assign_bitxor ||
692  statement==ID_assign_bitand ||
693  statement==ID_assign_lshr ||
694  statement==ID_assign_ashr ||
695  statement==ID_assign_shl ||
696  statement==ID_assign_mod)
697  remove_assignment(expr, dest, result_is_used, address_taken, mode);
698  else if(statement==ID_postincrement ||
699  statement==ID_postdecrement)
700  remove_post(expr, dest, mode, result_is_used);
701  else if(statement==ID_preincrement ||
702  statement==ID_predecrement)
703  remove_pre(expr, dest, result_is_used, address_taken, mode);
704  else if(statement==ID_cpp_new ||
705  statement==ID_cpp_new_array)
706  remove_cpp_new(expr, dest, result_is_used);
707  else if(statement==ID_cpp_delete ||
708  statement==ID_cpp_delete_array)
709  remove_cpp_delete(expr, dest);
710  else if(statement==ID_allocate)
711  remove_malloc(expr, dest, mode, result_is_used);
712  else if(statement==ID_temporary_object)
713  remove_temporary_object(expr, dest);
714  else if(statement==ID_statement_expression)
715  remove_statement_expression(expr, dest, mode, result_is_used);
716  else if(statement==ID_nondet)
717  {
718  // these are fine
719  }
720  else if(statement==ID_skip)
721  {
722  expr.make_nil();
723  }
724  else if(statement==ID_throw)
725  {
727  expr.find(ID_exception_list), expr.type(), expr.source_location()));
728  code.op0().operands().swap(expr.operands());
729  code.add_source_location() = expr.source_location();
731  std::move(code), expr.source_location(), THROW, nil_exprt(), {}));
732 
733  // the result can't be used, these are void
734  expr.make_nil();
735  }
736  else if(
737  statement == ID_overflow_plus || statement == ID_overflow_minus ||
738  statement == ID_overflow_mult)
739  {
741  to_side_effect_expr_overflow(expr), dest, result_is_used, mode);
742  }
743  else
744  {
745  UNREACHABLE;
746  }
747 }
exprt::copy_to_operands
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:155
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
goto_convertt::convert_function_call
void convert_function_call(const code_function_callt &code, goto_programt &dest, const irep_idt &mode)
Definition: goto_convert_function_call.cpp:18
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
to_code_expression
code_expressiont & to_code_expression(codet &code)
Definition: std_code.h:1428
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
Forall_operands
#define Forall_operands(it, expr)
Definition: expr.h:27
goto_convertt::ns
namespacet ns
Definition: goto_convert_class.h:52
to_side_effect_expr_overflow
const side_effect_expr_overflowt & to_side_effect_expr_overflow(const exprt &expr)
Cast an exprt to a side_effect_expr_overflowt.
Definition: c_expr.h:182
arith_tools.h
is_number
bool is_number(const typet &type)
Returns true if the type is a rational, real, integer, natural, complex, unsignedbv,...
Definition: mathematical_types.cpp:17
codet::op0
exprt & op0()
Definition: expr.h:125
side_effect_expr_overflowt::rhs
exprt & rhs()
Definition: c_expr.h:143
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
goto_convertt::replace_new_object
static void replace_new_object(const exprt &object, exprt &dest)
Definition: goto_convert_side_effect.cpp:409
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
irept::make_nil
void make_nil()
Definition: irep.h:454
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
typet
The type of an expression, extends irept.
Definition: type.h:28
fresh_symbol.h
goto_convertt::convert_frontend_decl
void convert_frontend_decl(const code_frontend_declt &, goto_programt &, const irep_idt &mode)
Definition: goto_convert.cpp:610
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
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
goto_convertt::has_function_call
static bool has_function_call(const exprt &expr)
Definition: goto_convert_side_effect.cpp:25
side_effect_expr_function_callt
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:1691
goto_convertt::tmp_symbol_prefix
std::string tmp_symbol_prefix
Definition: goto_convert_class.h:53
goto_convert_class.h
goto_programt::add
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:709
code_frontend_declt
A codet representing the declaration of a local variable.
Definition: std_code.h:346
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
side_effect_expr_statement_expressiont::statement
codet & statement()
Definition: std_code.h:1650
exprt
Base class for all expressions.
Definition: expr.h:55
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
binary_exprt
A base class for binary expressions.
Definition: std_expr.h:582
symbolt::base_name
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
overflow_result_exprt
An expression returning both the result of the arithmetic operation under wrap-around semantics as we...
Definition: bitvector_expr.h:1304
to_complex_type
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition: std_types.h:1102
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
to_side_effect_expr_statement_expression
side_effect_expr_statement_expressiont & to_side_effect_expr_statement_expression(exprt &expr)
Definition: std_code.h:1669
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
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
to_binary_expr
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:660
INVARIANT_WITH_DIAGNOSTICS
#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Same as invariant, with one or more diagnostics attached Diagnostics can be of any type that has a sp...
Definition: invariant.h:437
mathematical_types.h
goto_convertt::remove_overflow
void remove_overflow(side_effect_expr_overflowt &expr, goto_programt &dest, bool result_is_used, const irep_idt &mode)
Definition: goto_convert_side_effect.cpp:601
to_code
const codet & to_code(const exprt &expr)
Definition: std_code_base.h:104
THROW
@ THROW
Definition: goto_program.h:50
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
code_function_callt
goto_instruction_codet representation of a function call statement.
Definition: goto_instruction_code.h:271
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
side_effect_expr_overflowt::lhs
exprt & lhs()
Definition: c_expr.h:133
symbolt::mode
irep_idt mode
Language mode.
Definition: symbol.h:49
messaget::result
mstreamt & result() const
Definition: message.h:409
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
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
forall_operands
#define forall_operands(it, expr)
Definition: expr.h:20
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
binary_overflow_exprt
A Boolean expression returning true, iff operation kind would result in an overflow when applied to o...
Definition: bitvector_expr.h:704
goto_convertt::remove_assignment
void remove_assignment(side_effect_exprt &expr, goto_programt &dest, bool result_is_used, bool address_taken, const irep_idt &mode)
Definition: goto_convert_side_effect.cpp:38
c_expr.h
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
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
nil_exprt
The NIL expression.
Definition: std_expr.h:3025
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
code_assignt::lhs
exprt & lhs()
Definition: goto_instruction_code.h:43
goto_convertt::remove_malloc
void remove_malloc(side_effect_exprt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used)
Definition: goto_convert_side_effect.cpp:463
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
goto_convertt::remove_cpp_new
void remove_cpp_new(side_effect_exprt &expr, goto_programt &dest, bool result_is_used)
Definition: goto_convert_side_effect.cpp:420
irept::swap
void swap(irept &irep)
Definition: irep.h:442
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
symbol.h
Symbol table entry.
irept::id
const irep_idt & id() const
Definition: irep.h:396
complex_exprt
Complex constructor from a pair of numbers.
Definition: std_expr.h:1857
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
goto_convertt::remove_cpp_delete
void remove_cpp_delete(side_effect_exprt &expr, goto_programt &dest)
Definition: goto_convert_side_effect.cpp:447
goto_convertt::remove_post
void remove_post(side_effect_exprt &expr, goto_programt &dest, const irep_idt &mode, bool result_is_used)
Definition: goto_convert_side_effect.cpp:271
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
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
goto_programt::destructive_append
void destructive_append(goto_programt &p)
Appends the given program p to *this. p is destroyed.
Definition: goto_program.h:692
source_locationt
Definition: source_location.h:18
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
expr_util.h
Deprecated expression utility functions.
goto_convertt::remove_temporary_object
void remove_temporary_object(side_effect_exprt &expr, goto_programt &dest)
Definition: goto_convert_side_effect.cpp:496
side_effect_expr_overflowt::result
exprt & result()
Definition: c_expr.h:153
symbolt::location
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
symbolt
Symbol table entry.
Definition: symbol.h:27
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
side_effect_expr_function_callt::arguments
exprt::operandst & arguments()
Definition: std_code.h:1718
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2051
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
goto_convertt::remove_pre
void remove_pre(side_effect_exprt &expr, goto_programt &dest, bool result_is_used, bool address_taken, const irep_idt &mode)
Definition: goto_convert_side_effect.cpp:179
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
side_effect_expr_throwt
A side_effect_exprt representation of a side effect that throws an exception.
Definition: std_code.h:1756
goto_convertt::symbol_table
symbol_table_baset & symbol_table
Definition: goto_convert_class.h:51
to_code_block
const code_blockt & to_code_block(const codet &code)
Definition: std_code.h:203
goto_convertt::convert_cpp_delete
void convert_cpp_delete(const codet &code, goto_programt &dest)
Definition: goto_convert.cpp:765
goto_convertt::assignment_lhs_needs_temporary
static bool assignment_lhs_needs_temporary(const exprt &lhs)
Definition: goto_convert_class.h:96
code_expressiont::expression
const exprt & expression() const
Definition: std_code.h:1401
side_effect_expr_overflowt
A Boolean expression returning true, iff the result of performing operation kind on operands a and b ...
Definition: c_expr.h:116
code_blockt::find_last_statement
codet & find_last_statement()
Definition: std_code.cpp:99
side_effect_expr_function_callt::function
exprt & function()
Definition: std_code.h:1708
exprt::operands
operandst & operands()
Definition: expr.h:94
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
codet::get_statement
const irep_idt & get_statement() const
Definition: std_code_base.h:65
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
binary_exprt::op1
exprt & op1()
Definition: expr.h:128
goto_programt::instructiont
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:180
std_expr.h
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
c_types.h
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
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
side_effect_exprt
An expression containing a side effect.
Definition: std_code.h:1449
bitvector_expr.h
to_code_assign
const code_assignt & to_code_assign(const goto_instruction_codet &code)
Definition: goto_instruction_code.h:115
binary_exprt::op0
exprt & op0()
Definition: expr.h:125
code_expressiont
codet representation of an expression statement.
Definition: std_code.h:1393
codet
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:28
goto_convertt::make_temp_symbol
void make_temp_symbol(exprt &expr, const std::string &suffix, goto_programt &, const irep_idt &mode)
Definition: goto_convert.cpp:1884