CBMC
rewrite_union.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Symbolic Execution of ANSI-C
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "rewrite_union.h"
13 
14 #include <util/arith_tools.h>
15 #include <util/byte_operators.h>
16 #include <util/c_types.h>
17 #include <util/pointer_expr.h>
18 #include <util/std_code.h>
19 
21 
22 static bool have_to_rewrite_union(const exprt &expr)
23 {
24  if(expr.id()==ID_member)
25  {
26  const exprt &op=to_member_expr(expr).struct_op();
27 
28  if(op.type().id() == ID_union_tag || op.type().id() == ID_union)
29  return true;
30  }
31  else if(expr.id()==ID_union)
32  return true;
33 
34  forall_operands(it, expr)
35  if(have_to_rewrite_union(*it))
36  return true;
37 
38  return false;
39 }
40 
41 // inside an address of (&x), unions can simply
42 // be type casts and don't have to be re-written!
44 {
45  if(!have_to_rewrite_union(expr))
46  return;
47 
48  if(expr.id()==ID_index)
49  {
51  rewrite_union(to_index_expr(expr).index());
52  }
53  else if(expr.id()==ID_member)
54  rewrite_union_address_of(to_member_expr(expr).struct_op());
55  else if(expr.id()==ID_symbol)
56  {
57  // done!
58  }
59  else if(expr.id()==ID_dereference)
60  rewrite_union(to_dereference_expr(expr).pointer());
61 }
62 
65 void rewrite_union(exprt &expr)
66 {
67  if(expr.id()==ID_address_of)
68  {
70  return;
71  }
72 
73  if(!have_to_rewrite_union(expr))
74  return;
75 
76  Forall_operands(it, expr)
77  rewrite_union(*it);
78 
79  if(expr.id()==ID_member)
80  {
81  const exprt &op=to_member_expr(expr).struct_op();
82 
83  if(op.type().id() == ID_union_tag || op.type().id() == ID_union)
84  {
85  exprt offset = from_integer(0, c_index_type());
86  expr = make_byte_extract(op, offset, expr.type());
87  }
88  }
89  else if(expr.id()==ID_union)
90  {
91  const union_exprt &union_expr=to_union_expr(expr);
92  exprt offset = from_integer(0, c_index_type());
93  side_effect_expr_nondett nondet(expr.type(), expr.source_location());
94  expr = make_byte_update(nondet, offset, union_expr.op());
95  }
96 }
97 
99 {
100  for(auto &instruction : goto_function.body.instructions)
101  {
102  rewrite_union(instruction.code_nonconst());
103 
104  if(instruction.has_condition())
105  rewrite_union(instruction.condition_nonconst());
106  }
107 }
108 
109 void rewrite_union(goto_functionst &goto_functions)
110 {
111  for(auto &gf_entry : goto_functions.function_map)
112  rewrite_union(gf_entry.second);
113 }
114 
115 void rewrite_union(goto_modelt &goto_model)
116 {
117  rewrite_union(goto_model.goto_functions);
118 }
make_byte_extract
byte_extract_exprt make_byte_extract(const exprt &_op, const exprt &_offset, const typet &_type)
Construct a byte_extract_exprt with endianness and byte width matching the current configuration.
Definition: byte_operators.cpp:48
rewrite_union.h
Forall_operands
#define Forall_operands(it, expr)
Definition: expr.h:27
arith_tools.h
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
union_exprt
Union constructor from single element.
Definition: std_expr.h:1707
goto_model.h
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
to_union_expr
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
Definition: std_expr.h:1754
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
byte_operators.h
Expression classes for byte-level operators.
forall_operands
#define forall_operands(it, expr)
Definition: expr.h:20
member_exprt::struct_op
const exprt & struct_op() const
Definition: std_expr.h:2832
pointer_expr.h
rewrite_union
void rewrite_union(exprt &expr)
We rewrite u.c for unions u into byte_extract(u, 0), and { .c = v } into byte_update(NIL,...
Definition: rewrite_union.cpp:65
irept::id
const irep_idt & id() const
Definition: irep.h:396
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
std_code.h
goto_functionst::goto_functiont
::goto_functiont goto_functiont
Definition: goto_functions.h:27
side_effect_expr_nondett
A side_effect_exprt that returns a non-deterministically chosen value.
Definition: std_code.h:1519
have_to_rewrite_union
static bool have_to_rewrite_union(const exprt &expr)
Definition: rewrite_union.cpp:22
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
rewrite_union_address_of
void rewrite_union_address_of(exprt &expr)
Definition: rewrite_union.cpp:43
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
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
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
make_byte_update
byte_update_exprt make_byte_update(const exprt &_op, const exprt &_offset, const exprt &_value)
Construct a byte_update_exprt with endianness and byte width matching the current configuration.
Definition: byte_operators.cpp:54
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
c_types.h