@@ -16,8 +16,12 @@ Author: Peter Schrammel
16
16
#include < util/format_expr.h>
17
17
#include < util/format_type.h>
18
18
#include < util/fresh_symbol.h>
19
+ #include < util/pointer_expr.h>
20
+ #include < util/prefix.h>
21
+ #include < util/string_constant.h>
19
22
20
23
#include < langapi/language_util.h>
24
+ #include < linking/static_lifetime_init.h>
21
25
22
26
#include " goto_symex_state.h"
23
27
#include " shadow_memory_util.h"
@@ -99,34 +103,132 @@ void shadow_memoryt::symex_get_field(
99
103
// To be implemented
100
104
}
101
105
106
+ // TODO: the following 4 functions (`symex_field_static_init`,
107
+ // `symex_field_static_init_string_constant`,
108
+ // `symex_field_local_init`,
109
+ // `symex_field_dynamic_init`) do filtering on
110
+ // the input symbol name and then call `initialize_shadow_memory` accordingly.
111
+ // We want to refactor and improve the way the filtering is done, but given
112
+ // that we don't have an easy mechanism to validate that we haven't changed the
113
+ // behaviour, we want to postpone changing this until the full shadow memory
114
+ // functionalities are integrated and we have good regression/unit testing.
115
+
102
116
void shadow_memoryt::symex_field_static_init (
103
117
goto_symex_statet &state,
104
118
const ssa_exprt &lhs)
105
119
{
106
- // To be implemented
120
+ if (lhs.get_original_expr ().id () != ID_symbol)
121
+ return ;
122
+
123
+ const irep_idt &identifier =
124
+ to_symbol_expr (lhs.get_original_expr ()).get_identifier ();
125
+
126
+ if (state.source .function_id != INITIALIZE_FUNCTION)
127
+ return ;
128
+
129
+ if (
130
+ has_prefix (id2string (identifier), CPROVER_PREFIX) &&
131
+ !has_prefix (id2string (identifier), CPROVER_PREFIX " errno" ))
132
+ {
133
+ return ;
134
+ }
135
+
136
+ const symbolt &symbol = ns.lookup (identifier);
137
+
138
+ if (
139
+ (id2string (symbol.name ).find (" ::return_value" ) == std::string::npos &&
140
+ symbol.is_auxiliary ) ||
141
+ !symbol.is_static_lifetime )
142
+ return ;
143
+ if (id2string (symbol.name ).find (" __cs_" ) != std::string::npos)
144
+ return ;
145
+
146
+ const typet &type = symbol.type ;
147
+ log.debug () << " Shadow memory: global memory " << id2string (identifier)
148
+ << " of type " << from_type (ns, " " , type) << messaget::eom;
149
+
150
+ initialize_shadow_memory (
151
+ state, lhs, state.shadow_memory .fields .global_fields );
107
152
}
108
153
109
154
void shadow_memoryt::symex_field_static_init_string_constant (
110
155
goto_symex_statet &state,
111
156
const ssa_exprt &expr,
112
157
const exprt &rhs)
113
158
{
114
- // To be implemented
159
+ if (
160
+ expr.get_original_expr ().id () == ID_symbol &&
161
+ has_prefix (
162
+ id2string (to_symbol_expr (expr.get_original_expr ()).get_identifier ()),
163
+ CPROVER_PREFIX))
164
+ {
165
+ return ;
166
+ }
167
+ const index_exprt &index_expr =
168
+ to_index_expr (to_address_of_expr (rhs).object ());
169
+
170
+ const typet &type = index_expr.array ().type ();
171
+ log.debug () << " Shadow memory: global memory "
172
+ << id2string (to_string_constant (index_expr.array ()).get_value ())
173
+ << " of type " << from_type (ns, " " , type) << messaget::eom;
174
+
175
+ initialize_shadow_memory (
176
+ state, index_expr.array (), state.shadow_memory .fields .global_fields );
115
177
}
116
178
117
179
void shadow_memoryt::symex_field_local_init (
118
180
goto_symex_statet &state,
119
181
const ssa_exprt &expr)
120
182
{
121
- // To be implemented
183
+ const symbolt &symbol =
184
+ ns.lookup (to_symbol_expr (expr.get_original_expr ()).get_identifier ());
185
+
186
+ const std::string symbol_name = id2string (symbol.name );
187
+ if (
188
+ symbol.is_auxiliary &&
189
+ symbol_name.find (" ::return_value" ) == std::string::npos)
190
+ return ;
191
+ if (
192
+ symbol_name.find (" malloc::" ) != std::string::npos &&
193
+ (symbol_name.find (" malloc_size" ) != std::string::npos ||
194
+ symbol_name.find (" malloc_res" ) != std::string::npos ||
195
+ symbol_name.find (" record_malloc" ) != std::string::npos ||
196
+ symbol_name.find (" record_may_leak" ) != std::string::npos))
197
+ {
198
+ return ;
199
+ }
200
+ if (
201
+ symbol_name.find (" __builtin_alloca::" ) != std::string::npos &&
202
+ (symbol_name.find (" alloca_size" ) != std::string::npos ||
203
+ symbol_name.find (" record_malloc" ) != std::string::npos ||
204
+ symbol_name.find (" record_alloca" ) != std::string::npos ||
205
+ symbol_name.find (" res" ) != std::string::npos))
206
+ {
207
+ return ;
208
+ }
209
+ if (symbol_name.find (" __cs_" ) != std::string::npos)
210
+ return ;
211
+
212
+ const typet &type = expr.type ();
213
+ ssa_exprt expr_l1 = remove_level_2 (expr);
214
+ log.debug () << " Shadow memory: local memory "
215
+ << id2string (expr_l1.get_identifier ()) << " of type "
216
+ << from_type (ns, " " , type) << messaget::eom;
217
+
218
+ initialize_shadow_memory (
219
+ state, expr_l1, state.shadow_memory .fields .local_fields );
122
220
}
123
221
124
222
void shadow_memoryt::symex_field_dynamic_init (
125
223
goto_symex_statet &state,
126
224
const exprt &expr,
127
225
const side_effect_exprt &code)
128
226
{
129
- // To be implemented
227
+ log.debug () << " Shadow memory: dynamic memory of type "
228
+ << from_type (ns, " " , expr.type ()) << messaget::eom;
229
+
230
+ initialize_shadow_memory (
231
+ state, expr, state.shadow_memory .fields .global_fields );
130
232
}
131
233
132
234
shadow_memory_field_definitionst shadow_memoryt::gather_field_declarations (
0 commit comments