Skip to content

Commit 0bcfc48

Browse files
Merge pull request #1253 from peterschrammel/bugfix/json-output-arrays
Fix JSON array output
2 parents f77c97d + 2a40436 commit 0bcfc48

File tree

7 files changed

+59
-51
lines changed

7 files changed

+59
-51
lines changed
314 Bytes
Binary file not shown.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Test {
2+
public static void main(long[] a) {
3+
if(a.length<3)
4+
return;
5+
for(int i=0; i<a.length; i++) {
6+
a[i]=(long)i;
7+
}
8+
}
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
Test.class
3+
--cover location --trace --json-ui --unwind 5
4+
activate-multi-line-match
5+
EXIT=0
6+
SIGNAL=0
7+
"lhs": "dynamic_2_array\[1L\]",\n *"mode": "java",\n *"sourceLocation": \{\n *"bytecodeIndex": "15",\n *"file": "Test\.java",\n *"function": "java::Test\.main:\(\[J\)V",\n *"line": "6"\n *\},\n *"stepType": "assignment",\n *"thread": 0,\n *"value": \{\n *"binary": "0000000000000000000000000000000000000000000000000000000000000001",\n *"data": "1L",\n *"name": "integer",\n *"type": "long",\n *"width": 64
8+
--
9+
"name": "unknown"
10+
^warning: ignoring

src/goto-programs/builtin_functions.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ void goto_convertt::do_java_new_array(
705705
else
706706
allocate_data_type=data.type();
707707

708-
side_effect_exprt data_cpp_new_expr(ID_cpp_new_array, allocate_data_type);
708+
side_effect_exprt data_java_new_expr(ID_java_new_array, allocate_data_type);
709709

710710
// The instruction may specify a (hopefully small) upper bound on the
711711
// array size, in which case we allocate a fixed-length array that may
@@ -714,29 +714,29 @@ void goto_convertt::do_java_new_array(
714714
// backend.
715715
const irept size_bound=rhs.find(ID_length_upper_bound);
716716
if(size_bound.is_nil())
717-
data_cpp_new_expr.set(ID_size, rhs.op0());
717+
data_java_new_expr.set(ID_size, rhs.op0());
718718
else
719-
data_cpp_new_expr.set(ID_size, size_bound);
719+
data_java_new_expr.set(ID_size, size_bound);
720720

721721
// Must directly assign the new array to a temporary
722722
// because goto-symex will notice `x=side_effect_exprt` but not
723723
// `x=typecast_exprt(side_effect_exprt(...))`
724724
symbol_exprt new_array_data_symbol=
725725
new_tmp_symbol(
726-
data_cpp_new_expr.type(),
726+
data_java_new_expr.type(),
727727
"new_array_data",
728728
dest,
729729
location)
730730
.symbol_expr();
731731
goto_programt::targett t_p2=dest.add_instruction(ASSIGN);
732-
t_p2->code=code_assignt(new_array_data_symbol, data_cpp_new_expr);
732+
t_p2->code=code_assignt(new_array_data_symbol, data_java_new_expr);
733733
t_p2->source_location=location;
734734

735735
goto_programt::targett t_p=dest.add_instruction(ASSIGN);
736-
exprt cast_cpp_new=new_array_data_symbol;
737-
if(cast_cpp_new.type()!=data.type())
738-
cast_cpp_new=typecast_exprt(cast_cpp_new, data.type());
739-
t_p->code=code_assignt(data, cast_cpp_new);
736+
exprt cast_java_new=new_array_data_symbol;
737+
if(cast_java_new.type()!=data.type())
738+
cast_java_new=typecast_exprt(cast_java_new, data.type());
739+
t_p->code=code_assignt(data, cast_java_new);
740740
t_p->source_location=location;
741741

742742
// zero-initialize the data

src/goto-programs/json_goto_trace.cpp

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening
1717
#include <util/arith_tools.h>
1818
#include <util/config.h>
1919
#include <util/invariant.h>
20+
#include <util/simplify_expr.h>
2021

2122
#include <langapi/language_util.h>
2223

@@ -64,42 +65,11 @@ void remove_pointer_offsets(exprt &src, const symbol_exprt &array_symbol)
6465
remove_pointer_offsets(op, array_symbol);
6566
}
6667

67-
/// Simplify the expression in index as much as possible to try to get an
68-
/// unsigned constant.
69-
/// \param idx: an expression representing an index in an array
70-
/// \param out: a reference to an unsigned value of type size_t, which will hold
71-
/// the result of the simplification if it is successful
72-
/// \return Boolean flag that is true if the `idx` expression could not be
73-
/// simplified into a unsigned constant value.
74-
bool simplify_index(const exprt &idx, std::size_t &out)
75-
{
76-
if(idx.id()==ID_constant)
77-
{
78-
std::string value_str(id2string(to_constant_expr(idx).get_value()));
79-
mp_integer int_value=binary2integer(value_str, false);
80-
if(int_value>std::numeric_limits<std::size_t>::max())
81-
return true;
82-
out=int_value.to_long();
83-
return false;
84-
}
85-
else if(idx.id()==ID_plus)
86-
{
87-
std::size_t l, r;
88-
if(!simplify_index(idx.op0(), l) && !simplify_index(idx.op1(), r))
89-
{
90-
out=l+r;
91-
return false;
92-
}
93-
}
94-
95-
return true;
96-
}
97-
9868
/// Simplify an expression before putting it in the json format
9969
/// \param src: an expression potentialy containing array accesses (index_expr)
10070
/// \return an expression similar in meaning to src but where array accesses
10171
/// have been simplified
102-
exprt simplify_array_access(const exprt &src)
72+
exprt simplify_array_access(const exprt &src, const namespacet &ns)
10373
{
10474
if(src.id()==ID_index && to_index_expr(src).array().id()==ID_symbol)
10575
{
@@ -108,6 +78,7 @@ exprt simplify_array_access(const exprt &src)
10878
exprt simplified_index=to_index_expr(src).index();
10979
// We remove potential appearances of `pointer_offset(array_symbol)`
11080
remove_pointer_offsets(simplified_index, array_symbol);
81+
simplified_index=simplify_expr(simplified_index, ns);
11182
return index_exprt(array_symbol, simplified_index);
11283
}
11384
else if(src.id()==ID_index && to_index_expr(src).array().id()==ID_array)
@@ -117,8 +88,10 @@ exprt simplify_array_access(const exprt &src)
11788
remove_pointer_offsets(index);
11889

11990
// We look for an actual integer value for the index
120-
std::size_t i;
121-
if(!simplify_index(index, i))
91+
index=simplify_expr(index, ns);
92+
unsigned i;
93+
if(index.id()==ID_constant &&
94+
!to_unsigned_integer(to_constant_expr(index), i))
12295
return to_index_expr(src).array().operands()[i];
12396
}
12497
return src;
@@ -196,7 +169,7 @@ void convert(
196169
DATA_INVARIANT(
197170
step.full_lhs.is_not_nil(),
198171
"full_lhs in assignment must not be nil");
199-
exprt simplified=simplify_array_access(step.full_lhs);
172+
exprt simplified=simplify_array_access(step.full_lhs, ns);
200173
full_lhs_string=from_expr(ns, identifier, simplified);
201174

202175
const symbolt *symbol;
@@ -210,7 +183,8 @@ void convert(
210183
type_string=from_type(ns, identifier, symbol->type);
211184

212185
json_assignment["mode"]=json_stringt(id2string(symbol->mode));
213-
exprt simplified=simplify_array_access(step.full_lhs_value);
186+
exprt simplified=simplify_array_access(step.full_lhs_value, ns);
187+
214188
full_lhs_value=json(simplified, ns, symbol->mode);
215189
}
216190
else

src/goto-symex/symex_assign.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ void goto_symext::symex_assign(
6060
throw "symex_assign: unexpected function call: "+id2string(identifier);
6161
}
6262
else if(statement==ID_cpp_new ||
63-
statement==ID_cpp_new_array)
63+
statement==ID_cpp_new_array ||
64+
statement==ID_java_new_array)
6465
symex_cpp_new(state, lhs, side_effect_expr);
6566
else if(statement==ID_malloc)
6667
symex_malloc(state, lhs, side_effect_expr);

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com
2323
#include <util/simplify_expr.h>
2424
#include <util/prefix.h>
2525
#include <util/string2int.h>
26-
26+
#include <util/invariant_utils.h>
2727
#include <util/c_types.h>
2828

2929
#include <linking/zero_initializer.h>
@@ -361,6 +361,11 @@ void goto_symext::symex_output(
361361
target.output(state.guard.as_expr(), state.source, output_id, args);
362362
}
363363

364+
/// Handles side effects of type 'new' for C++ and 'new array'
365+
/// for C++ and Java language modes
366+
/// \param state: Symex state
367+
/// \param lhs: left-hand side of assignment
368+
/// \param code: right-hand side containing side effect
364369
void goto_symext::symex_cpp_new(
365370
statet &state,
366371
const exprt &lhs,
@@ -371,7 +376,8 @@ void goto_symext::symex_cpp_new(
371376
if(code.type().id()!=ID_pointer)
372377
throw "new expected to return pointer";
373378

374-
do_array=(code.get(ID_statement)==ID_cpp_new_array);
379+
do_array=(code.get(ID_statement)==ID_cpp_new_array ||
380+
code.get(ID_statement)==ID_java_new_array);
375381

376382
dynamic_counter++;
377383

@@ -384,7 +390,13 @@ void goto_symext::symex_cpp_new(
384390
"dynamic_"+count_string+"_value";
385391
symbol.name="symex_dynamic::"+id2string(symbol.base_name);
386392
symbol.is_lvalue=true;
387-
symbol.mode=ID_cpp;
393+
if(code.get(ID_statement)==ID_cpp_new_array ||
394+
code.get(ID_statement)==ID_cpp_new)
395+
symbol.mode=ID_cpp;
396+
else if(code.get(ID_statement)==ID_java_new_array)
397+
symbol.mode=ID_java;
398+
else
399+
INVARIANT_WITH_IREP(false, "Unexpected side effect expression", code);
388400

389401
if(do_array)
390402
{
@@ -397,7 +409,6 @@ void goto_symext::symex_cpp_new(
397409
else
398410
symbol.type=code.type().subtype();
399411

400-
// symbol.type.set("#active", symbol_expr(active_symbol));
401412
symbol.type.set("#dynamic", true);
402413

403414
new_symbol_table.add(symbol);
@@ -425,7 +436,10 @@ void goto_symext::symex_cpp_delete(
425436
statet &state,
426437
const codet &code)
427438
{
428-
// bool do_array=code.get(ID_statement)==ID_cpp_delete_array;
439+
// TODO
440+
#if 0
441+
bool do_array=code.get(ID_statement)==ID_cpp_delete_array;
442+
#endif
429443
}
430444

431445
void goto_symext::symex_trace(

0 commit comments

Comments
 (0)