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