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