Skip to content

Commit 1b97f3d

Browse files
Add support for unbounded-size objects
They get allocated 2^32 address space each (of a 2^64 sized space) using the sparse-vector memory representation to keep the actual storage requirements sensible. Original patch: From: Chris Smowton <[email protected]> Date: Tue, 21 Mar 2017 17:13:43 +0000 Subject: [PATCH 2/3] Add support for unbounded-size objects Corrected linting issues Using empty, and comments on get_size
1 parent 5d2919b commit 1b97f3d

File tree

1 file changed

+62
-15
lines changed

1 file changed

+62
-15
lines changed

src/goto-programs/interpreter.cpp

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -597,16 +597,25 @@ exprt interpretert::get_value(
597597
exprt result=array_exprt(to_array_type(real_type));
598598
const exprt &size_expr=static_cast<const exprt &>(type.find(ID_size));
599599
size_t subtype_size=get_size(type.subtype());
600-
mp_integer mp_count;
601-
to_integer(size_expr, mp_count);
602-
unsigned count=integer2unsigned(mp_count);
600+
std::size_t count;
601+
if(size_expr.id()!=ID_constant)
602+
{
603+
count=base_address_to_actual_size(offset)/subtype_size;
604+
}
605+
else
606+
{
607+
mp_integer mp_count;
608+
to_integer(size_expr, mp_count);
609+
count=integer2size_t(mp_count);
610+
}
603611

604612
// Retrieve the value for each member in the array
605613
result.reserve_operands(count);
606614
for(unsigned i=0; i<count; i++)
607615
{
608-
const exprt operand=get_value(type.subtype(),
609-
offset+i*subtype_size);
616+
const exprt operand=get_value(
617+
type.subtype(),
618+
offset+i*subtype_size);
610619
result.copy_to_operands(operand);
611620
}
612621
return result;
@@ -663,9 +672,17 @@ exprt interpretert::get_value(
663672

664673
// Get size of array
665674
size_t subtype_size=get_size(type.subtype());
666-
mp_integer mp_count;
667-
to_integer(size_expr, mp_count);
668-
unsigned count=integer2unsigned(mp_count);
675+
unsigned count;
676+
if(unbounded_size(type))
677+
{
678+
count=base_address_to_actual_size(offset)/subtype_size;
679+
}
680+
else
681+
{
682+
mp_integer mp_count;
683+
to_integer(size_expr, mp_count);
684+
count=integer2unsigned(mp_count);
685+
}
669686

670687
// Retrieve the value for each member in the array
671688
result.reserve_operands(count);
@@ -917,7 +934,9 @@ void interpretert::execute_function_call()
917934
// of the interpreter run to fill it with the corresponding data
918935
goto_trace_stept &trace_step=steps.get_last_step();
919936
std::size_t address=integer2size_t(a);
937+
#if 0
920938
const memory_cellt &cell=memory[address];
939+
#endif
921940
const irep_idt &identifier=address_to_identifier(address);
922941
trace_step.identifier=identifier;
923942

@@ -1113,7 +1132,7 @@ Function: interpretert::build_memory_map
11131132
11141133
Inputs:
11151134
1116-
Outputs: Updtaes the memory map to include variable id if it does
1135+
Outputs: Updates the memory map to include variable id if it does
11171136
not exist
11181137
11191138
Purpose: Populates dynamic entries of the memory map
@@ -1152,20 +1171,45 @@ mp_integer interpretert::build_memory_map(
11521171
return address;
11531172
}
11541173

1174+
bool interpretert::unbounded_size(const typet &type)
1175+
{
1176+
if(type.id()==ID_array)
1177+
{
1178+
const exprt &size=to_array_type(type).size();
1179+
if(size.id()==ID_infinity)
1180+
return true;
1181+
return unbounded_size(type.subtype());
1182+
}
1183+
else if(type.id()==ID_struct)
1184+
{
1185+
const auto &st=to_struct_type(type);
1186+
if(st.components().empty())
1187+
return false;
1188+
return unbounded_size(st.components().back().type());
1189+
}
1190+
return false;
1191+
}
1192+
11551193
/*******************************************************************\
11561194
11571195
Function: interpretert::get_size
11581196
11591197
Inputs:
1198+
type - a structured type
11601199
1161-
Outputs:
1200+
Outputs: Size of the given type
11621201
1163-
Purpose: Retrieves the actual size of the provided structured type
1202+
Purpose: Retrieves the actual size of the provided structured type.
1203+
Unbounded objects get allocated 2^32 address space each
1204+
(of a 2^64 sized space).
11641205
11651206
\*******************************************************************/
11661207

11671208
size_t interpretert::get_size(const typet &type)
11681209
{
1210+
if(unbounded_size(type))
1211+
return 2ULL << 32ULL;
1212+
11691213
if(type.id()==ID_struct)
11701214
{
11711215
const struct_typet::componentst &components=
@@ -1253,7 +1297,7 @@ exprt interpretert::get_value(const irep_idt &id)
12531297
symbol_exprt symbol_expr(id, get_type);
12541298
mp_integer whole_lhs_object_address=evaluate_address(symbol_expr);
12551299

1256-
return get_value(get_type, integer2unsigned(whole_lhs_object_address));
1300+
return get_value(get_type, integer2size_t(whole_lhs_object_address));
12571301
}
12581302

12591303
/*******************************************************************\
@@ -1295,10 +1339,13 @@ Function: interpretert::print_memory
12951339

12961340
void interpretert::print_memory(bool input_flags)
12971341
{
1298-
for(size_t i=0; i<memory.size(); i++)
1342+
for(const auto &cell_address : memory)
12991343
{
1300-
memory_cellt &cell=memory[i];
1301-
debug() << cell.identifier << "[" << cell.offset << "]"
1344+
std::size_t i=cell_address.first;
1345+
const memory_cellt &cell=cell_address.second;
1346+
const auto identifier=address_to_identifier(i);
1347+
const auto offset=address_to_offset(i);
1348+
debug() << identifier << "[" << offset << "]"
13021349
<< "=" << cell.value << eom;
13031350
if(input_flags)
13041351
debug() << "(" << static_cast<int>(cell.initialized) << ")"

0 commit comments

Comments
 (0)