CBMC
Loading...
Searching...
No Matches
uninitialized.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Detection for Uninitialized Local Variables
4
5Author: Daniel Kroening
6
7Date: January 2010
8
9\*******************************************************************/
10
13
14#include "uninitialized.h"
15
17
19{
20public:
25
26 void add_assertions(
28 goto_programt &goto_program);
29
30protected:
34
35 // The variables that need tracking,
36 // i.e., are uninitialized and may be read?
37 std::set<irep_idt> tracking;
38
40};
41
44{
45 std::list<exprt> objects=objects_read(*i_it);
46
47 for(const auto &object : objects)
48 {
49 if(object.id() == ID_symbol)
50 {
51 const irep_idt &identifier = to_symbol_expr(object).get_identifier();
52 const std::set<irep_idt> &uninitialized=
53 uninitialized_analysis[i_it].uninitialized;
54 if(uninitialized.find(identifier)!=uninitialized.end())
55 tracking.insert(identifier);
56 }
57 else if(object.id() == ID_dereference)
58 {
59 }
60 }
61}
62
64 const irep_idt &function_identifier,
65 goto_programt &goto_program)
66{
67 uninitialized_analysis(function_identifier, goto_program, ns);
68
69 // find out which variables need tracking
70
71 tracking.clear();
74
75 // add tracking symbols to symbol table
76 for(std::set<irep_idt>::const_iterator
77 it=tracking.begin();
78 it!=tracking.end();
79 it++)
80 {
81 const symbolt &symbol=ns.lookup(*it);
82
83 symbolt new_symbol{
84 id2string(symbol.name) + "#initialized", bool_typet(), symbol.mode};
85 new_symbol.base_name=id2string(symbol.base_name)+"#initialized";
86 new_symbol.location=symbol.location;
87 new_symbol.module=symbol.module;
88 new_symbol.is_thread_local=true;
89 new_symbol.is_file_local=true;
90 new_symbol.is_lvalue=true;
91
92 symbol_table.insert(std::move(new_symbol));
93 }
94
96 {
98
99 if(instruction.is_decl())
100 {
101 // if we track it, add declaration and assignment
102 // for tracking variable!
103
104 const irep_idt &identifier = instruction.decl_symbol().get_identifier();
105
106 if(tracking.find(identifier)!=tracking.end())
107 {
109 id2string(identifier)+"#initialized";
110
111 symbol_exprt symbol_expr(new_identifier, bool_typet());
113 goto_programt::make_decl(symbol_expr, instruction.source_location());
114
116 symbol_expr, false_exprt(), instruction.source_location());
117
119 goto_program.insert_after(i_it, std::move(i1));
120 goto_program.insert_after(i1_it, std::move(i2));
121 i_it++, i_it++;
122 }
123 }
124 else
125 {
126 std::list<exprt> read=objects_read(instruction);
127 std::list<exprt> written=objects_written(instruction);
128
129 // if(instruction.is_function_call())
130 // const code_function_callt &code_function_call=
131 // to_code_function_call(instruction.code);
132
133 const std::set<irep_idt> &uninitialized=
134 uninitialized_analysis[i_it].uninitialized;
135
136 // check tracking variables
137 for(const auto &object : read)
138 {
139 if(object.id() == ID_symbol)
140 {
141 const irep_idt &identifier = to_symbol_expr(object).get_identifier();
142
143 if(uninitialized.find(identifier)!=uninitialized.end())
144 {
145 INVARIANT(
146 tracking.find(identifier) != tracking.end(), "not tracked");
147 const irep_idt new_identifier=id2string(identifier)+"#initialized";
148
149 // insert assertion
151 annotated_location.set_comment(
152 "use of uninitialized local variable " + id2string(identifier));
153 annotated_location.set_property_class("uninitialized local");
157
158 goto_program.insert_before_swap(i_it, assertion);
159 i_it++;
160 }
161 }
162 }
163
164 // set tracking variables
165 for(const auto &object : written)
166 {
167 if(object.id() == ID_symbol)
168 {
169 const irep_idt &identifier = to_symbol_expr(object).get_identifier();
170
171 if(tracking.find(identifier)!=tracking.end())
172 {
173 const irep_idt new_identifier=id2string(identifier)+"#initialized";
174
175 goto_programt::instructiont assignment =
178 true_exprt(),
179 instruction.source_location());
180
181 goto_program.insert_before_swap(i_it, assignment);
182 i_it++;
183 }
184 }
185 }
186 }
187 }
188}
189
191{
192 for(auto &gf_entry : goto_model.goto_functions.function_map)
193 {
194 uninitializedt uninitialized(goto_model.symbol_table);
195
196 uninitialized.add_assertions(gf_entry.first, gf_entry.second.body);
197 }
198}
199
201 const goto_modelt &goto_model,
202 std::ostream &out)
203{
204 const namespacet ns(goto_model.symbol_table);
205
206 for(const auto &gf_entry : goto_model.goto_functions.function_map)
207 {
208 if(gf_entry.second.body_available())
209 {
210 out << "////\n";
211 out << "//// Function: " << gf_entry.first << '\n';
212 out << "////\n\n";
213 uninitialized_analysist uninitialized_analysis;
214 uninitialized_analysis(gf_entry.first, gf_entry.second.body, ns);
215 uninitialized_analysis.output(
216 ns, gf_entry.first, gf_entry.second.body, out);
217 }
218 }
219}
virtual void output(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program, std::ostream &out) const
Output the abstract states for a single function.
Definition ai.cpp:39
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
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
The Boolean constant false.
Definition std_expr.h:3199
function_mapt function_map
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
const symbol_exprt & decl_symbol() const
Get the declared symbol for DECL.
const source_locationt & source_location() const
A generic container class for the GOTO intermediate representation of one function.
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
instructionst::iterator targett
instructionst::const_iterator const_targett
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
targett insert_after(const_targett target)
Insertion after the instruction pointed-to by the given instruction iterator target.
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Expression to hold a symbol (variable)
Definition std_expr.h:131
The symbol table base class interface.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
Symbol table entry.
Definition symbol.h:28
bool is_thread_local
Definition symbol.h:71
source_locationt location
Source code location of definition of symbol.
Definition symbol.h:37
irep_idt name
The unique identifier.
Definition symbol.h:40
irep_idt irep_idt base_name
Name of module the symbol belongs to.
Definition symbol.h:46
irep_idt mode
Language mode.
Definition symbol.h:49
The Boolean constant true.
Definition std_expr.h:3190
void add_assertions(const irep_idt &function_identifer, goto_programt &goto_program)
symbol_table_baset & symbol_table
std::set< irep_idt > tracking
void get_tracking(goto_programt::const_targett i_it)
which variables need tracking, i.e., are uninitialized and may be read?
uninitialized_analysist uninitialized_analysis
uninitializedt(symbol_table_baset &_symbol_table)
void objects_read(const exprt &src, std::list< exprt > &dest)
void objects_written(const exprt &src, std::list< exprt > &dest)
#define forall_goto_program_instructions(it, program)
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
int __CPROVER_ID java::java io InputStream read
Definition java.io.c:5
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
void add_uninitialized_locals_assertions(goto_modelt &goto_model)
void show_uninitialized(const goto_modelt &goto_model, std::ostream &out)
Detection for Uninitialized Local Variables.
Detection for Uninitialized Local Variables.