@@ -11,11 +11,14 @@ Author: Peter Schrammel
11
11
12
12
#include " shadow_memory.h"
13
13
14
+ #include < util/bitvector_types.h>
15
+ #include < util/format_type.h>
14
16
#include < util/fresh_symbol.h>
15
17
16
18
#include < langapi/language_util.h>
17
19
18
20
#include " goto_symex_state.h"
21
+ #include " shadow_memory_util.h"
19
22
20
23
void shadow_memoryt::initialize_shadow_memory (
21
24
goto_symex_statet &state,
@@ -95,17 +98,84 @@ void shadow_memoryt::symex_field_dynamic_init(
95
98
}
96
99
97
100
shadow_memory_field_definitionst shadow_memoryt::gather_field_declarations (
98
- abstract_goto_modelt &goto_model,
101
+ const abstract_goto_modelt &goto_model,
99
102
message_handlert &message_handler)
100
103
{
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;
104
147
}
105
148
106
149
void shadow_memoryt::convert_field_declaration (
107
150
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)
109
154
{
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;
111
181
}
0 commit comments