Skip to content

Commit d84ee18

Browse files
peterschrammelEnrico Steffinlongo
authored and
Enrico Steffinlongo
committed
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 2cd10e5 commit d84ee18

File tree

2 files changed

+83
-9
lines changed

2 files changed

+83
-9
lines changed

src/goto-symex/shadow_memory.cpp

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2023
void shadow_memoryt::initialize_shadow_memory(
2124
goto_symex_statet &state,
@@ -95,17 +98,84 @@ void shadow_memoryt::symex_field_dynamic_init(
9598
}
9699

97100
shadow_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 =
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;
104147
}
105148

106149
void shadow_memoryt::convert_field_declaration(
107150
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)
109154
{
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;
111181
}

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)