Skip to content

Commit aaf1cba

Browse files
Implement shadow_memoryt::gather_field_declarations
Gathers the available shadow memory field definitions (__CPROVER_field_decl calls) from the goto model and stores them in a shadow_memory_field_definitionst.
1 parent c8f307e commit aaf1cba

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

src/goto-symex/shadow_memory.cpp

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ Author: Peter Schrammel
1111

1212
#include "shadow_memory.h"
1313

14+
#include <util/format_type.h>
1415
#include <util/fresh_symbol.h>
1516

1617
#include <langapi/language_util.h>
1718

1819
#include "goto_symex_state.h"
20+
#include "shadow_memory_util.h"
1921

2022
void shadow_memoryt::initialize_shadow_memory(
2123
goto_symex_statet &state,
@@ -93,17 +95,84 @@ void shadow_memoryt::symex_field_dynamic_init(
9395
}
9496

9597
shadow_memory_field_definitionst shadow_memoryt::gather_field_declarations(
96-
abstract_goto_modelt &goto_model,
98+
const abstract_goto_modelt &goto_model,
9799
message_handlert &message_handler)
98100
{
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;
102144
}
103145

104146
void shadow_memoryt::convert_field_declaration(
105147
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)
107151
{
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;
109178
}

src/goto-symex/shadow_memory.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class shadow_memoryt
5050
/// \param message_handler For logging
5151
/// \return The field definitions
5252
static shadow_memory_field_definitionst gather_field_declarations(
53-
abstract_goto_modelt &goto_model,
53+
const abstract_goto_modelt &goto_model,
5454
message_handlert &message_handler);
5555

5656
/// Initialize global-scope shadow memory for global/static variables.
@@ -100,9 +100,13 @@ class shadow_memoryt
100100
/// Converts a field declaration
101101
/// \param code_function_call The __CPROVER_field_decl_* call
102102
/// \param fields The field declaration to be extended
103-
void convert_field_declaration(
103+
/// \param is_global True if the declaration is global
104+
/// \param message_handler For logging
105+
static void convert_field_declaration(
104106
const code_function_callt &code_function_call,
105-
shadow_memory_field_definitionst::field_definitiont &fields);
107+
shadow_memory_field_definitionst::field_definitiont &fields,
108+
bool is_global,
109+
message_handlert &message_handler);
106110

107111
/// Allocates and initializes a shadow memory field for the given original
108112
/// memory.

0 commit comments

Comments
 (0)