Skip to content

Commit abbafd2

Browse files
authored
Merge pull request #4525 from antlechner/antonia/array-index-arithmetic
Refactor element access of pointer arrays into a separate function
2 parents 4ef4cdc + 2088544 commit abbafd2

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Author: Daniel Kroening, [email protected]
88

99
#include "java_object_factory.h"
1010

11+
#include <util/array_element_from_pointer.h>
1112
#include <util/expr_initializer.h>
1213
#include <util/nondet.h>
1314
#include <util/nondet_bool.h>
@@ -1200,10 +1201,10 @@ void java_object_factoryt::array_loop_init_code(
12001201
assignments.add(std::move(max_test));
12011202
}
12021203

1203-
const dereference_exprt arraycellref{
1204-
plus_exprt{array_init_symexpr, counter_expr}};
1204+
const dereference_exprt element_at_counter =
1205+
array_element_from_pointer(array_init_symexpr, counter_expr);
12051206

1206-
bool new_item_is_primitive = arraycellref.type().id() != ID_pointer;
1207+
bool new_item_is_primitive = element_at_counter.type().id() != ID_pointer;
12071208

12081209
// Use a temporary to initialise a new, or update an existing, non-primitive.
12091210
// This makes it clearer that in a sequence like
@@ -1213,17 +1214,17 @@ void java_object_factoryt::array_loop_init_code(
12131214
exprt init_expr;
12141215
if(new_item_is_primitive)
12151216
{
1216-
init_expr = arraycellref;
1217+
init_expr = element_at_counter;
12171218
}
12181219
else
12191220
{
12201221
init_expr = allocate_objects.allocate_automatic_local_object(
1221-
arraycellref.type(), "new_array_item");
1222+
element_at_counter.type(), "new_array_item");
12221223

12231224
// If we're updating an existing array item, read the existing object that
12241225
// we (may) alter:
12251226
if(update_in_place != update_in_placet::NO_UPDATE_IN_PLACE)
1226-
assignments.add(code_assignt(init_expr, arraycellref));
1227+
assignments.add(code_assignt(init_expr, element_at_counter));
12271228
}
12281229

12291230
// MUST_UPDATE_IN_PLACE only applies to this object.
@@ -1249,7 +1250,7 @@ void java_object_factoryt::array_loop_init_code(
12491250
{
12501251
// We used a temporary variable to update or initialise an array item;
12511252
// now write it into the array:
1252-
assignments.add(code_assignt(arraycellref, init_expr));
1253+
assignments.add(code_assignt(element_at_counter, init_expr));
12531254
}
12541255

12551256
exprt java_one=from_integer(1, java_int_type());
@@ -1389,11 +1390,9 @@ bool java_object_factoryt::gen_nondet_enum_init(
13891390
allocate_objects,
13901391
assignments);
13911392

1392-
// Generate statement using pointer arithmetic to access array element:
1393-
// expr = (expr.type())*(enum_array_expr + index_expr);
1394-
plus_exprt plus(enum_array_expr, index_expr);
1395-
const dereference_exprt arraycellref(plus);
1396-
code_assignt enum_assign(expr, typecast_exprt(arraycellref, expr.type()));
1393+
const dereference_exprt element_at_index =
1394+
array_element_from_pointer(enum_array_expr, index_expr);
1395+
code_assignt enum_assign(expr, typecast_exprt(element_at_index, expr.type()));
13971396
assignments.add(enum_assign);
13981397

13991398
return true;

src/util/array_element_from_pointer.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*******************************************************************\
2+
3+
Module: Element access in a pointer array
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_UTIL_ARRAY_ELEMENT_FROM_POINTER_H
10+
#define CPROVER_UTIL_ARRAY_ELEMENT_FROM_POINTER_H
11+
12+
#include "std_expr.h"
13+
14+
/// Generate statement using pointer arithmetic to access the element at the
15+
/// given index of a pointer array:
16+
/// `*(pointer + index)`
17+
/// Arrays are sometimes (always in JBMC) represented as a pointer to their
18+
/// first element, especially when their length in uncertain, as the length is
19+
/// part of any array type. But we know the type of the first element of the
20+
/// array, so we work with that instead.
21+
/// \param pointer: pointer to the first element of an array
22+
/// \param index: index of the element to access
23+
/// \return expression representing the (\p index)'th element of the array
24+
dereference_exprt
25+
array_element_from_pointer(const exprt &pointer, const exprt &index)
26+
{
27+
PRECONDITION(can_cast_type<pointer_typet>(pointer.type()));
28+
PRECONDITION(
29+
index.type().id() == ID_signedbv || index.type().id() == ID_unsignedbv);
30+
return dereference_exprt{plus_exprt{pointer, index}};
31+
}
32+
33+
#endif // CPROVER_UTIL_ARRAY_ELEMENT_FROM_POINTER_H

0 commit comments

Comments
 (0)