CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
invariant_propagation.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Invariant Propagation
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
13
14#include <util/simplify_expr.h>
15#include <util/std_expr.h>
16
19 : public ai_domain_factoryt<invariant_set_domaint>
20{
21public:
25
26 std::unique_ptr<statet> make(locationt l) const override
27 {
28 auto p = std::make_unique<invariant_set_domaint>(
30 CHECK_RETURN(p->is_bottom());
31
32 return std::unique_ptr<statet>(p.release());
33 }
34
35private:
37};
38
49
51{
52 for(auto &state :
53 static_cast<location_sensitive_storaget &>(*storage).internal())
54 static_cast<invariant_set_domaint &>(*(state.second))
55 .invariant_set.make_true();
56}
57
59{
60 for(auto &state :
61 static_cast<location_sensitive_storaget &>(*storage).internal())
62 static_cast<invariant_set_domaint &>(*(state.second))
63 .invariant_set.make_false();
64}
65
67 const goto_programt &goto_program)
68{
69 // get the globals
72
73 // get the locals
75 goto_program.get_decl_identifiers(locals);
76
77 // cache the list for the locals to speed things up
78 typedef std::unordered_map<irep_idt, object_listt> object_cachet;
80
82 {
83 #if 0
84 invariant_sett &is=(*this)[i_it].invariant_set;
85
86 is.add_objects(globals);
87 #endif
88
89 for(const auto &local : locals)
90 {
91 // cache hit?
92 object_cachet::const_iterator e_it=object_cache.find(local);
93
94 if(e_it==object_cache.end())
95 {
96 const symbolt &symbol=ns.lookup(local);
97
98 object_listt &objects=object_cache[local];
99 get_objects(symbol, objects);
100 #if 0
101 is.add_objects(objects);
102 #endif
103 }
104 #if 0
105 else
106 is.add_objects(e_it->second);
107 #endif
108 }
109 }
110}
111
113 const symbolt &symbol,
114 object_listt &dest)
115{
116 std::list<exprt> object_list;
117
119
120 for(const auto &expr : object_list)
121 dest.push_back(object_store.add(expr));
122}
123
125 const exprt &src,
126 std::list<exprt> &dest)
127{
128 const typet &t = src.type();
129
130 if(
131 t.id() == ID_struct || t.id() == ID_union || t.id() == ID_struct_tag ||
132 t.id() == ID_union_tag)
133 {
135 (t.id() == ID_struct_tag || t.id() == ID_union_tag)
136 ? ns.follow_tag(to_struct_or_union_tag_type(t))
138
139 for(const auto &component : struct_type.components())
140 {
142 src, component.get_name(), component.type());
143 // recursive call
145 }
146 }
147 else if(t.id()==ID_array)
148 {
149 // get_objects_rec(identifier, suffix+"[]", t.subtype(), dest);
150 // we don't track these
151 }
152 else if(check_type(t))
153 {
154 dest.push_back(src);
155 }
156}
157
159 const goto_functionst &goto_functions)
160{
161 // get the globals
164
165 for(const auto &gf_entry : goto_functions.function_map)
166 {
167 // get the locals
168 std::set<irep_idt> locals;
169 get_local_identifiers(gf_entry.second, locals);
170
171 const goto_programt &goto_program = gf_entry.second.body;
172
173 // cache the list for the locals to speed things up
174 typedef std::unordered_map<irep_idt, object_listt> object_cachet;
176
178 {
179 #if 0
180 invariant_sett &is=(*this)[i_it].invariant_set;
181
182 is.add_objects(globals);
183 #endif
184
185 for(const auto &local : locals)
186 {
187 // cache hit?
188 object_cachet::const_iterator e_it=object_cache.find(local);
189
190 if(e_it==object_cache.end())
191 {
192 const symbolt &symbol=ns.lookup(local);
193
194 object_listt &objects=object_cache[local];
195 get_objects(symbol, objects);
196 #if 0
197 is.add_objects(objects);
198 #endif
199 }
200 #if 0
201 else
202 is.add_objects(e_it->second);
203 #endif
204 }
205 }
206 }
207}
208
210 object_listt &dest)
211{
212 // static ones
213 for(const auto &symbol_pair : ns.get_symbol_table().symbols)
214 {
215 if(symbol_pair.second.is_lvalue && symbol_pair.second.is_static_lifetime)
216 {
217 get_objects(symbol_pair.second, dest);
218 }
219 }
220}
221
223{
224 if(type.id()==ID_pointer)
225 return true;
226 else if(
227 type.id() == ID_struct || type.id() == ID_union ||
228 type.id() == ID_struct_tag || type.id() == ID_union_tag)
229 {
230 return false;
231 }
232 else if(type.id()==ID_array)
233 return false;
234 else if(type.id()==ID_unsignedbv ||
235 type.id()==ID_signedbv)
236 return true;
237 else if(type.id()==ID_bool)
238 return true;
239
240 return false;
241}
242
244 const irep_idt &function,
245 const goto_programt &goto_program)
246{
247 baset::initialize(function, goto_program);
248
249 add_objects(goto_program);
250}
251
253{
254 for(auto &gf_entry : goto_functions.function_map)
255 simplify(gf_entry.second.body);
256}
257
259{
261 {
262 if(!i_it->is_assert())
263 continue;
264
265 // find invariant set
266 const auto &d = (*this)[i_it];
267 if(d.is_bottom())
268 continue;
269
270 const invariant_sett &invariant_set = d.invariant_set;
271
272 exprt simplified_guard(i_it->condition());
273
274 invariant_set.simplify(simplified_guard);
276
277 if(invariant_set.implies(simplified_guard).is_true())
278 i_it->condition_nonconst() = true_exprt();
279 }
280}
virtual void initialize(const irep_idt &function_id, const goto_programt &goto_program)
Initialize all the abstract states for a single function.
Definition ai.cpp:194
ai_domain_factory_baset::locationt locationt
Definition ai_domain.h:203
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
A collection of goto functions.
function_mapt function_map
A generic container class for the GOTO intermediate representation of one function.
std::set< irep_idt > decl_identifierst
void get_decl_identifiers(decl_identifierst &decl_identifiers) const
get the variables in decl statements
unsigned add(const exprt &expr)
void add_objects(const goto_programt &goto_program)
void simplify(goto_programt &goto_program)
void get_objects(const symbolt &symbol, object_listt &dest)
void initialize(const irep_idt &function, const goto_programt &goto_program) override
Initialize all the abstract states for a single function.
void get_objects_rec(const exprt &src, std::list< exprt > &dest)
std::list< unsigned > object_listt
bool check_type(const typet &type) const
void get_globals(object_listt &globals)
invariant_propagationt(const namespacet &_ns, value_setst &_value_sets)
Pass the necessary arguments to the invariant_set_domaint's when constructed.
std::unique_ptr< statet > make(locationt l) const override
invariant_set_domain_factoryt(invariant_propagationt &_ip)
void simplify(exprt &expr) const
tvt implies(const exprt &expr) const
const irep_idt & id() const
Definition irep.h:388
The most conventional storage; one domain per location.
Definition ai_storage.h:154
state_mapt & internal(void)
Definition ai_storage.h:169
Extract member of struct or union.
Definition std_expr.h:2971
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
Base type for structs and unions.
Definition std_types.h:62
Symbol table entry.
Definition symbol.h:28
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition symbol.cpp:121
The Boolean constant true.
Definition std_expr.h:3190
bool is_true() const
Definition threeval.h:25
The type of an expression, extends irept.
Definition type.h:29
void get_local_identifiers(const goto_functiont &goto_function, std::set< irep_idt > &dest)
Return in dest the identifiers of the local variables declared in the goto_function and the identifie...
#define forall_goto_program_instructions(it, program)
#define Forall_goto_program_instructions(it, program)
Invariant Propagation.
STL namespace.
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:97
API to expression classes.
const struct_or_union_tag_typet & to_struct_or_union_tag_type(const typet &type)
Cast a typet to a struct_or_union_tag_typet.
Definition std_types.h:478
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition std_types.h:214