CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
postcondition.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Symbolic Execution
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
12#include "postcondition.h"
13
14#include <util/find_symbols.h>
15#include <util/pointer_expr.h>
16#include <util/std_expr.h>
17
19
20#include "renaming_level.h"
22
24{
25public:
34
35protected:
36 const namespacet &ns;
40
41public:
42 void compute(exprt &dest);
43
44protected:
45 void strengthen(exprt &dest);
46 void weaken(exprt &dest);
47 bool is_used_address_of(const exprt &expr, const irep_idt &identifier);
48 bool is_used(const exprt &expr, const irep_idt &identifier);
49};
50
52 const namespacet &ns,
53 const value_sett &value_set,
54 const symex_target_equationt &equation,
55 const goto_symex_statet &s,
56 exprt &dest)
57{
58 for(symex_target_equationt::SSA_stepst::const_iterator
59 it=equation.SSA_steps.begin();
60 it!=equation.SSA_steps.end();
61 it++)
62 {
63 postconditiont postcondition(ns, value_set, *it, s);
64 postcondition.compute(dest);
65 if(dest.is_false())
66 return;
67 }
68}
69
71 const exprt &expr,
72 const irep_idt &identifier)
73{
74 if(expr.id()==ID_symbol)
75 {
76 // leave alone
77 }
78 else if(expr.id()==ID_index)
79 {
80 return is_used_address_of(to_index_expr(expr).array(), identifier) ||
81 is_used(to_index_expr(expr).index(), identifier);
82 }
83 else if(expr.id()==ID_member)
84 {
85 return is_used_address_of(to_member_expr(expr).compound(), identifier);
86 }
87 else if(expr.id()==ID_dereference)
88 {
89 return is_used(to_dereference_expr(expr).pointer(), identifier);
90 }
91
92 return false;
93}
94
96{
97 // weaken due to assignment
98 weaken(dest);
99
100 // strengthen due to assignment
101 strengthen(dest);
102}
103
105{
106 if(dest.id()==ID_and &&
107 dest.type()==bool_typet()) // this distributes over "and"
108 {
109 Forall_operands(it, dest)
110 weaken(*it);
111
112 return;
113 }
114
115 // we are lazy:
116 // if lhs is mentioned in dest, we use "true".
117
118 const irep_idt &lhs_identifier=SSA_step.ssa_lhs.get_object_name();
119
120 if(is_used(dest, lhs_identifier))
121 dest=true_exprt();
122
123 // otherwise, no weakening needed
124}
125
127{
128 const irep_idt &lhs_identifier=SSA_step.ssa_lhs.get_object_name();
129
130 if(!is_used(SSA_step.ssa_rhs, lhs_identifier))
131 {
132 // we don't do arrays or structs
133 if(SSA_step.ssa_lhs.type().id()==ID_array ||
134 SSA_step.ssa_lhs.type().id()==ID_struct)
135 return;
136
137 exprt equality =
139
140 if(dest.is_true())
141 dest.swap(equality);
142 else
143 dest=and_exprt(dest, equality);
144 }
145}
146
148 const exprt &expr,
149 const irep_idt &identifier)
150{
151 if(expr.id()==ID_address_of)
152 {
153 return is_used_address_of(to_address_of_expr(expr).object(), identifier);
154 }
155 else if(is_ssa_expr(expr))
156 {
157 return to_ssa_expr(expr).get_object_name()==identifier;
158 }
159 else if(expr.id()==ID_symbol)
160 {
161 return to_symbol_expr(expr).get_identifier() == identifier;
162 }
163 else if(expr.id()==ID_dereference)
164 {
165 // aliasing may happen here
166 for(const exprt &e :
167 value_set.get_value_set(to_dereference_expr(expr).pointer(), ns))
168 {
169 if(has_symbol_expr(get_original_name(e), identifier, false))
170 return true;
171 }
172
173 return false;
174 }
175 else
176 {
177 for(const auto &op : expr.operands())
178 {
179 if(is_used(op, identifier))
180 return true;
181 }
182 }
183
184 return false;
185}
Single SSA step in the equation.
Definition ssa_step.h:47
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Boolean AND.
Definition std_expr.h:2125
The Boolean type.
Definition std_types.h:36
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Equality.
Definition std_expr.h:1366
Base class for all expressions.
Definition expr.h:56
bool is_true() const
Return whether the expression is a constant representing true.
Definition expr.cpp:27
bool is_false() const
Return whether the expression is a constant representing false.
Definition expr.cpp:34
typet & type()
Return the type of the expression.
Definition expr.h:84
operandst & operands()
Definition expr.h:94
Central data structure: state.
void swap(irept &irep)
Definition irep.h:434
const irep_idt & id() const
Definition irep.h:388
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
const SSA_stept & SSA_step
const namespacet & ns
bool is_used(const exprt &expr, const irep_idt &identifier)
void strengthen(exprt &dest)
const value_sett & value_set
const goto_symex_statet & s
void weaken(exprt &dest)
bool is_used_address_of(const exprt &expr, const irep_idt &identifier)
postconditiont(const namespacet &_ns, const value_sett &_value_set, const SSA_stept &_SSA_step, const goto_symex_statet &_s)
void compute(exprt &dest)
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
The Boolean constant true.
Definition std_expr.h:3190
State type in value_set_domaint, used in value-set analysis and goto-symex.
Definition value_set.h:44
#define Forall_operands(it, expr)
Definition expr.h:27
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...
API to expression classes for Pointers.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
void postcondition(const namespacet &ns, const value_sett &value_set, const symex_target_equationt &equation, const goto_symex_statet &s, exprt &dest)
Generate Equation using Symbolic Execution.
exprt get_original_name(exprt expr)
Undo all levels of renaming.
Renaming levels.
bool is_ssa_expr(const exprt &expr)
Definition ssa_expr.h:125
const ssa_exprt & to_ssa_expr(const exprt &expr)
Cast a generic exprt to an ssa_exprt.
Definition ssa_expr.h:145
API to expression classes.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition std_expr.h:1538
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition std_expr.h:3063
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
Generate Equation using Symbolic Execution.
Value Set.