@@ -11,11 +11,14 @@ Author: Peter Schrammel
1111
1212#include " shadow_memory.h"
1313
14+ #include < util/bitvector_types.h>
15+ #include < util/format_type.h>
1416#include < util/fresh_symbol.h>
1517
1618#include < langapi/language_util.h>
1719
1820#include " goto_symex_state.h"
21+ #include " shadow_memory_util.h"
1922
2023void shadow_memoryt::initialize_shadow_memory (
2124 goto_symex_statet &state,
@@ -95,17 +98,84 @@ void shadow_memoryt::symex_field_dynamic_init(
9598}
9699
97100shadow_memory_field_definitionst shadow_memoryt::gather_field_declarations (
98- abstract_goto_modelt &goto_model,
101+ const abstract_goto_modelt &goto_model,
99102 message_handlert &message_handler)
100103{
101- // To be implemented
102-
103- return shadow_memory_field_definitionst ();
104+ shadow_memory_field_definitionst field_definitions;
105+
106+ // Gather shadow memory declarations from goto model
107+ for (const auto &goto_function : goto_model.get_goto_functions ().function_map )
108+ {
109+ const auto &goto_program = goto_function.second .body ;
110+ forall_goto_program_instructions (target, goto_program)
111+ {
112+ if (!target->is_function_call ())
113+ continue ;
114+
115+ const auto &code_function_call =
116+ to_code_function_call (target->get_code ());
117+ const exprt &function = code_function_call.function ();
118+
119+ if (function.id () != ID_symbol)
120+ continue ;
121+
122+ const irep_idt &identifier = to_symbol_expr (function).get_identifier ();
123+
124+ if (
125+ identifier ==
126+ CPROVER_PREFIX SHADOW_MEMORY_FIELD_DECL SHADOW_MEMORY_GLOBAL_SCOPE)
127+ {
128+ convert_field_declaration (
129+ code_function_call,
130+ field_definitions.global_fields ,
131+ true ,
132+ message_handler);
133+ }
134+ else if (
135+ identifier ==
136+ CPROVER_PREFIX SHADOW_MEMORY_FIELD_DECL SHADOW_MEMORY_LOCAL_SCOPE)
137+ {
138+ convert_field_declaration (
139+ code_function_call,
140+ field_definitions.local_fields ,
141+ false ,
142+ message_handler);
143+ }
144+ }
145+ }
146+ return field_definitions;
104147}
105148
106149void shadow_memoryt::convert_field_declaration (
107150 const code_function_callt &code_function_call,
108- shadow_memory_field_definitionst::field_definitiont &fields)
151+ shadow_memory_field_definitionst::field_definitiont &fields,
152+ bool is_global,
153+ message_handlert &message_handler)
109154{
110- // To be implemented
155+ INVARIANT (
156+ code_function_call.arguments ().size () == 2 ,
157+ std::string (CPROVER_PREFIX) + SHADOW_MEMORY_FIELD_DECL +
158+ (is_global ? SHADOW_MEMORY_GLOBAL_SCOPE : SHADOW_MEMORY_LOCAL_SCOPE) +
159+ " requires 2 arguments" );
160+ irep_idt field_name = extract_field_name (code_function_call.arguments ()[0 ]);
161+
162+ exprt expr = code_function_call.arguments ()[1 ];
163+
164+ messaget log (message_handler);
165+ log.debug () << " Shadow memory: declare " << (is_global ? " global " : " local " )
166+ << " field " << id2string (field_name) << " of type "
167+ << format (expr.type ()) << messaget::eom;
168+ if (!can_cast_type<bitvector_typet>(expr.type ()))
169+ {
170+ throw unsupported_operation_exceptiont (
171+ " A shadow memory field must be of a bitvector type." );
172+ }
173+ if (to_bitvector_type (expr.type ()).get_width () > 8 )
174+ {
175+ throw unsupported_operation_exceptiont (
176+ " A shadow memory field must not be larger than 8 bits." );
177+ }
178+
179+ // record the field's initial value (and type)
180+ fields[field_name] = expr;
111181}
0 commit comments