@@ -1173,13 +1173,26 @@ assigns_clause_array_targett::assigns_clause_array_targett(
1173
1173
code_contractst &contract,
1174
1174
messaget &log_parameter,
1175
1175
const irep_idt &function_id)
1176
- : assigns_clause_targett(Array, object_ptr, contract, log_parameter),
1176
+ : assigns_clause_targett(
1177
+ Array,
1178
+ to_range_exprt (object_ptr).lower(),
1179
+ contract,
1180
+ log_parameter),
1177
1181
lower_offset_object(),
1178
1182
upper_offset_object(),
1179
1183
array_standin_variable(typet()),
1180
1184
lower_offset_variable(typet()),
1181
1185
upper_offset_variable(typet())
1182
1186
{
1187
+ const exprt &array = to_range_exprt (object_ptr).lower ();
1188
+ const exprt &range = to_range_exprt (object_ptr).upper ();
1189
+
1190
+ // If the range doesn't have operands, it is just a single value
1191
+ const exprt &lower_operand =
1192
+ range.has_operands () ? to_range_exprt (range).lower () : range;
1193
+ const exprt &upper_operand =
1194
+ range.has_operands () ? to_range_exprt (range).upper () : range;
1195
+
1183
1196
const symbolt &function_symbol = contract.ns .lookup (function_id);
1184
1197
1185
1198
// Declare a new symbol to stand in for the reference
@@ -1198,13 +1211,24 @@ assigns_clause_array_targett::assigns_clause_array_targett(
1198
1211
code_assignt (array_standin_variable, pointer_object),
1199
1212
function_symbol.location ));
1200
1213
1201
- if (object_ptr .id () == ID_address_of )
1214
+ if (lower_operand .id () == ID_constant )
1202
1215
{
1203
- exprt constant_size =
1204
- get_size (object_ptr.type ().subtype (), contract.ns , log );
1216
+ int lowerbase = std::stoi (
1217
+ to_constant_expr (lower_operand).get (ID_C_base).c_str (), nullptr , 10 );
1218
+ lower_bound = std::stoi (
1219
+ to_constant_expr (lower_operand).get_value ().c_str (), nullptr , lowerbase);
1220
+
1221
+ irep_idt lower_const_string (
1222
+ from_integer (lower_bound, integer_typet ()).get_value ());
1223
+ irep_idt lower_const_irep (lower_const_string);
1224
+ constant_exprt lower_val_const (lower_const_irep, lower_operand.type ());
1225
+
1226
+ exprt lower_constant_size =
1227
+ get_size (array.type ().subtype (), contract.ns , log );
1205
1228
lower_offset_object = typecast_exprt (
1206
1229
mult_exprt (
1207
- typecast_exprt (object_ptr, unsigned_long_int_type ()), constant_size),
1230
+ typecast_exprt (lower_val_const, unsigned_long_int_type ()),
1231
+ lower_constant_size),
1208
1232
signed_int_type ());
1209
1233
1210
1234
// Declare a new symbol to stand in for the reference
@@ -1222,10 +1246,78 @@ assigns_clause_array_targett::assigns_clause_array_targett(
1222
1246
init_block.add (goto_programt::make_assignment (
1223
1247
code_assignt (lower_offset_variable, lower_offset_object),
1224
1248
function_symbol.location ));
1249
+ }
1250
+ else
1251
+ {
1252
+ exprt lower_constant_size =
1253
+ get_size (array.type ().subtype (), contract.ns , log );
1254
+ lower_offset_object = typecast_exprt (
1255
+ mult_exprt (
1256
+ typecast_exprt (lower_operand, unsigned_long_int_type ()),
1257
+ lower_constant_size),
1258
+ signed_int_type ());
1259
+
1260
+ // Declare a new symbol to stand in for the reference
1261
+ symbolt lower_standin_symbol = contract.new_tmp_symbol (
1262
+ lower_offset_object.type (),
1263
+ function_symbol.location ,
1264
+ function_id,
1265
+ function_symbol.mode );
1266
+
1267
+ lower_offset_variable = lower_standin_symbol.symbol_expr ();
1225
1268
1269
+ // Add array temp to variable initialization block
1270
+ init_block.add (goto_programt::make_decl (
1271
+ lower_offset_variable, function_symbol.location ));
1272
+ init_block.add (goto_programt::make_assignment (
1273
+ code_assignt (lower_offset_variable, lower_offset_object),
1274
+ function_symbol.location ));
1275
+ }
1276
+
1277
+ if (upper_operand.id () == ID_constant)
1278
+ {
1279
+ int upperbase = std::stoi (
1280
+ to_constant_expr (upper_operand).get (ID_C_base).c_str (), nullptr , 10 );
1281
+ upper_bound = std::stoi (
1282
+ to_constant_expr (upper_operand).get_value ().c_str (), nullptr , upperbase);
1283
+
1284
+ irep_idt upper_const_string (
1285
+ from_integer (upper_bound, integer_typet ()).get_value ());
1286
+ irep_idt upper_const_irep (upper_const_string);
1287
+ constant_exprt upper_val_const (upper_const_irep, upper_operand.type ());
1288
+
1289
+ exprt upper_constant_size =
1290
+ get_size (array.type ().subtype (), contract.ns , log );
1291
+ upper_offset_object = typecast_exprt (
1292
+ mult_exprt (
1293
+ typecast_exprt (upper_val_const, unsigned_long_int_type ()),
1294
+ upper_constant_size),
1295
+ signed_int_type ());
1296
+
1297
+ // Declare a new symbol to stand in for the reference
1298
+ symbolt upper_standin_symbol = contract.new_tmp_symbol (
1299
+ upper_offset_object.type (),
1300
+ function_symbol.location ,
1301
+ function_id,
1302
+ function_symbol.mode );
1303
+
1304
+ upper_offset_variable = upper_standin_symbol.symbol_expr ();
1305
+
1306
+ // Add array temp to variable initialization block
1307
+ init_block.add (goto_programt::make_decl (
1308
+ upper_offset_variable, function_symbol.location ));
1309
+ init_block.add (goto_programt::make_assignment (
1310
+ code_assignt (upper_offset_variable, upper_offset_object),
1311
+ function_symbol.location ));
1312
+ }
1313
+ else
1314
+ {
1315
+ exprt upper_constant_size =
1316
+ get_size (array.type ().subtype (), contract.ns , log );
1226
1317
upper_offset_object = typecast_exprt (
1227
1318
mult_exprt (
1228
- typecast_exprt (object_ptr, unsigned_long_int_type ()), constant_size),
1319
+ typecast_exprt (upper_operand, unsigned_long_int_type ()),
1320
+ upper_constant_size),
1229
1321
signed_int_type ());
1230
1322
1231
1323
// Declare a new symbol to stand in for the reference
@@ -1267,7 +1359,7 @@ assigns_clause_array_targett::havoc_code(source_locationt location) const
1267
1359
exprt array_type_size =
1268
1360
get_size (pointer_object.type ().subtype (), contract.ns , log );
1269
1361
1270
- for (mp_integer i = lower_bound; i < upper_bound; ++i)
1362
+ for (mp_integer i = lower_bound; i <= upper_bound; ++i)
1271
1363
{
1272
1364
irep_idt offset_string (from_integer (i, integer_typet ()).get_value ());
1273
1365
irep_idt offset_irep (offset_string);
@@ -1360,7 +1452,7 @@ assigns_clauset::~assigns_clauset()
1360
1452
1361
1453
assigns_clause_targett *assigns_clauset::add_target (exprt current_operation)
1362
1454
{
1363
- if (current_operation.id () == ID_address_of )
1455
+ if (current_operation.id () == ID_range )
1364
1456
{
1365
1457
assigns_clause_array_targett *array_target =
1366
1458
new assigns_clause_array_targett (
0 commit comments