@@ -16,8 +16,12 @@ Author: Peter Schrammel
1616#include < util/format_expr.h>
1717#include < util/format_type.h>
1818#include < util/fresh_symbol.h>
19+ #include < util/pointer_expr.h>
20+ #include < util/prefix.h>
21+ #include < util/string_constant.h>
1922
2023#include < langapi/language_util.h>
24+ #include < linking/static_lifetime_init.h>
2125
2226#include " goto_symex_state.h"
2327#include " shadow_memory_util.h"
@@ -99,34 +103,132 @@ void shadow_memoryt::symex_get_field(
99103 // To be implemented
100104}
101105
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+
102116void shadow_memoryt::symex_field_static_init (
103117 goto_symex_statet &state,
104118 const ssa_exprt &lhs)
105119{
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 );
107152}
108153
109154void shadow_memoryt::symex_field_static_init_string_constant (
110155 goto_symex_statet &state,
111156 const ssa_exprt &expr,
112157 const exprt &rhs)
113158{
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 );
115177}
116178
117179void shadow_memoryt::symex_field_local_init (
118180 goto_symex_statet &state,
119181 const ssa_exprt &expr)
120182{
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 );
122220}
123221
124222void shadow_memoryt::symex_field_dynamic_init (
125223 goto_symex_statet &state,
126224 const exprt &expr,
127225 const side_effect_exprt &code)
128226{
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 );
130232}
131233
132234shadow_memory_field_definitionst shadow_memoryt::gather_field_declarations (
0 commit comments