@@ -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,83 @@ 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 = to_code_function_call (target->code ());
116+ const exprt &function = code_function_call.function ();
117+
118+ if (function.id () != ID_symbol)
119+ continue ;
120+
121+ const irep_idt &identifier = to_symbol_expr (function).get_identifier ();
122+
123+ if (
124+ identifier ==
125+ CPROVER_PREFIX SHADOW_MEMORY_FIELD_DECL SHADOW_MEMORY_GLOBAL_SCOPE)
126+ {
127+ convert_field_declaration (
128+ code_function_call,
129+ field_definitions.global_fields ,
130+ true ,
131+ message_handler);
132+ }
133+ else if (
134+ identifier ==
135+ CPROVER_PREFIX SHADOW_MEMORY_FIELD_DECL SHADOW_MEMORY_LOCAL_SCOPE)
136+ {
137+ convert_field_declaration (
138+ code_function_call,
139+ field_definitions.local_fields ,
140+ false ,
141+ message_handler);
142+ }
143+ }
144+ }
145+ return field_definitions;
104146}
105147
106148void shadow_memoryt::convert_field_declaration (
107149 const code_function_callt &code_function_call,
108- shadow_memory_field_definitionst::field_definitiont &fields)
150+ shadow_memory_field_definitionst::field_definitiont &fields,
151+ bool is_global,
152+ message_handlert &message_handler)
109153{
110- // To be implemented
154+ INVARIANT (
155+ code_function_call.arguments ().size () == 2 ,
156+ std::string (CPROVER_PREFIX) + SHADOW_MEMORY_FIELD_DECL +
157+ (is_global ? SHADOW_MEMORY_GLOBAL_SCOPE : SHADOW_MEMORY_LOCAL_SCOPE) +
158+ " requires 2 arguments" );
159+ irep_idt field_name = extract_field_name (code_function_call.arguments ()[0 ]);
160+
161+ exprt expr = code_function_call.arguments ()[1 ];
162+
163+ messaget log (message_handler);
164+ log.debug () << " Shadow memory: declare " << (is_global ? " global " : " local " )
165+ << " field " << id2string (field_name) << " of type "
166+ << format (expr.type ()) << messaget::eom;
167+ if (!can_cast_type<bitvector_typet>(expr.type ()))
168+ {
169+ throw unsupported_operation_exceptiont (
170+ " A shadow memory field must be of a bitvector type." );
171+ }
172+ if (to_bitvector_type (expr.type ()).get_width () > 8 )
173+ {
174+ throw unsupported_operation_exceptiont (
175+ " A shadow memory field must not be larger than 8 bits." );
176+ }
177+
178+ // record the field's initial value (and type)
179+ fields[field_name] = expr;
111180}
0 commit comments