Skip to content

Commit 28fb804

Browse files
authored
Merge pull request diffblue#1288 from tautschnig/develop-json
JSON code cleanup
2 parents 8254a3f + 27fd210 commit 28fb804

File tree

7 files changed

+100
-92
lines changed

7 files changed

+100
-92
lines changed

src/cbmc/bmc_cover.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ bool bmc_covert::operator()()
394394
json_objectt json_input;
395395
json_input["id"]=json_stringt(id2string(step.io_id));
396396
if(step.io_args.size()==1)
397-
json_input["value"]=json(step.io_args.front(), bmc.ns);
397+
json_input["value"]=
398+
json(step.io_args.front(), bmc.ns, ID_unknown);
398399
json_test.push_back(json_input);
399400
}
400401
}

src/goto-programs/json_goto_trace.cpp

Lines changed: 3 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -21,82 +21,6 @@ Author: Daniel Kroening
2121

2222
#include <langapi/language_util.h>
2323

24-
/// Replaces in src, expressions of the form pointer_offset(constant) by that
25-
/// constant.
26-
/// \param src: an expression
27-
void remove_pointer_offsets(exprt &src)
28-
{
29-
if(src.id()==ID_pointer_offset &&
30-
src.op0().id()==ID_constant &&
31-
src.op0().type().id()==ID_pointer)
32-
{
33-
std::string binary_str=id2string(to_constant_expr(src.op0()).get_value());
34-
// The constant address consists of OBJECT-ID || OFFSET.
35-
// Shift out the object-identifier bits, leaving only the offset:
36-
mp_integer offset=binary2integer(
37-
binary_str.substr(config.bv_encoding.object_bits), false);
38-
src=from_integer(offset, src.type());
39-
}
40-
else
41-
for(auto &op : src.operands())
42-
remove_pointer_offsets(op);
43-
}
44-
45-
/// Replaces in src, expressions of the form pointer_offset(array_symbol) by a
46-
/// constant value of 0. This is meant to simplify array expressions.
47-
/// \param src: an expression
48-
/// \param array_symbol: a symbol expression representing an array
49-
void remove_pointer_offsets(exprt &src, const symbol_exprt &array_symbol)
50-
{
51-
if(src.id()==ID_pointer_offset &&
52-
src.op0().id()==ID_constant &&
53-
src.op0().op0().id()==ID_address_of &&
54-
src.op0().op0().op0().id()==ID_index)
55-
{
56-
const index_exprt &idx=to_index_expr(src.op0().op0().op0());
57-
const irep_idt &array_id=to_symbol_expr(idx.array()).get_identifier();
58-
if(idx.array().id()==ID_symbol &&
59-
array_id==array_symbol.get_identifier() &&
60-
to_constant_expr(idx.index()).value_is_zero_string())
61-
src=from_integer(0, src.type());
62-
}
63-
else
64-
for(auto &op : src.operands())
65-
remove_pointer_offsets(op, array_symbol);
66-
}
67-
68-
/// Simplify an expression before putting it in the json format
69-
/// \param src: an expression potentialy containing array accesses (index_expr)
70-
/// \return an expression similar in meaning to src but where array accesses
71-
/// have been simplified
72-
exprt simplify_array_access(const exprt &src, const namespacet &ns)
73-
{
74-
if(src.id()==ID_index && to_index_expr(src).array().id()==ID_symbol)
75-
{
76-
// Case where the array is a symbol.
77-
const symbol_exprt &array_symbol=to_symbol_expr(to_index_expr(src).array());
78-
exprt simplified_index=to_index_expr(src).index();
79-
// We remove potential appearances of `pointer_offset(array_symbol)`
80-
remove_pointer_offsets(simplified_index, array_symbol);
81-
simplified_index=simplify_expr(simplified_index, ns);
82-
return index_exprt(array_symbol, simplified_index);
83-
}
84-
else if(src.id()==ID_index && to_index_expr(src).array().id()==ID_array)
85-
{
86-
// Case where the array is given by an array of expressions
87-
exprt index=to_index_expr(src).index();
88-
remove_pointer_offsets(index);
89-
90-
// We look for an actual integer value for the index
91-
index=simplify_expr(index, ns);
92-
unsigned i;
93-
if(index.id()==ID_constant &&
94-
!to_unsigned_integer(to_constant_expr(index), i))
95-
return to_index_expr(src).array().operands()[i];
96-
}
97-
return src;
98-
}
99-
10024
/// Produce a json representation of a trace.
10125
/// \param ns: a namespace
10226
/// \param goto_trace: a trace in a goto program
@@ -169,7 +93,7 @@ void convert(
16993
DATA_INVARIANT(
17094
step.full_lhs.is_not_nil(),
17195
"full_lhs in assignment must not be nil");
172-
exprt simplified=simplify_array_access(step.full_lhs, ns);
96+
exprt simplified=simplify_expr(step.full_lhs, ns);
17397
full_lhs_string=from_expr(ns, identifier, simplified);
17498

17599
const symbolt *symbol;
@@ -183,7 +107,7 @@ void convert(
183107
type_string=from_type(ns, identifier, symbol->type);
184108

185109
json_assignment["mode"]=json_stringt(id2string(symbol->mode));
186-
exprt simplified=simplify_array_access(step.full_lhs_value, ns);
110+
exprt simplified=simplify_expr(step.full_lhs_value, ns);
187111

188112
full_lhs_value=json(simplified, ns, symbol->mode);
189113
}
@@ -192,7 +116,7 @@ void convert(
192116
DATA_INVARIANT(
193117
step.full_lhs_value.is_not_nil(),
194118
"full_lhs_value in assignment must not be nil");
195-
full_lhs_value=json(step.full_lhs_value, ns);
119+
full_lhs_value=json(step.full_lhs_value, ns, ID_unknown);
196120
}
197121

198122
json_assignment["value"]=full_lhs_value;

src/symex/symex_cover.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ void symex_parse_optionst::report_cover(
164164
json_objectt json_input;
165165
json_input["id"]=json_stringt(id2string(step.io_id));
166166
if(step.io_args.size()==1)
167-
json_input["value"]=json(step.io_args.front(), ns);
167+
json_input["value"]=
168+
json(step.io_args.front(), ns, ID_unknown);
168169
json_test.push_back(json_input);
169170
}
170171
}

src/util/json_expr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ class namespacet;
2323
json_objectt json(
2424
const exprt &,
2525
const namespacet &,
26-
const irep_idt &mode=ID_unknown);
26+
const irep_idt &mode);
2727

2828
json_objectt json(
2929
const typet &,
3030
const namespacet &,
31-
const irep_idt &mode=ID_unknown);
31+
const irep_idt &mode);
3232

3333
json_objectt json(const source_locationt &);
3434

src/util/simplify_expr_pointer.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,41 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr)
375375

376376
return false;
377377
}
378-
else if(ptr.id()==ID_constant &&
379-
ptr.get(ID_value)==ID_NULL)
378+
else if(ptr.id()==ID_constant)
380379
{
381-
expr=from_integer(0, expr.type());
380+
constant_exprt &c_ptr=to_constant_expr(ptr);
382381

383-
simplify_node(expr);
382+
if(c_ptr.get_value()==ID_NULL ||
383+
c_ptr.value_is_zero_string())
384+
{
385+
expr=from_integer(0, expr.type());
384386

385-
return false;
387+
simplify_node(expr);
388+
389+
return false;
390+
}
391+
else
392+
{
393+
// this is a pointer, we can't use to_integer
394+
mp_integer number=binary2integer(id2string(c_ptr.get_value()), false);
395+
// a null pointer would have been caught above, return value 0
396+
// will indicate that conversion failed
397+
if(number==0)
398+
return true;
399+
400+
// The constant address consists of OBJECT-ID || OFFSET.
401+
mp_integer offset_bits=
402+
pointer_offset_bits(ptr.type(), ns)-config.bv_encoding.object_bits;
403+
number%=power(2, offset_bits);
404+
405+
expr=from_integer(number, expr.type());
406+
407+
simplify_node(expr);
408+
409+
return false;
410+
}
411+
412+
return true;
386413
}
387414

388415
return true;

unit/Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ SRC = src/expr/require_expr.cpp \
55
src/ansi-c/c_to_expr.cpp \
66
unit_tests.cpp \
77
catch_example.cpp \
8-
util/expr_iterator.cpp \
9-
analyses/call_graph.cpp \
10-
java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \
118
# Empty last line
129

1310
# Test source files
@@ -23,8 +20,10 @@ SRC += unit_tests.cpp \
2320
solvers/refinement/string_constraint_generator_valueof/get_numeric_value_from_character.cpp \
2421
solvers/refinement/string_constraint_generator_valueof/is_digit_with_radix.cpp \
2522
solvers/refinement/string_constraint_instantiation/instantiate_not_contains.cpp \
26-
solvers/refinement/string_refinement/substitute_array_list.cpp \
2723
solvers/refinement/string_refinement/concretize_array.cpp \
24+
solvers/refinement/string_refinement/substitute_array_list.cpp \
25+
util/expr_iterator.cpp \
26+
util/simplify_expr.cpp \
2827
catch_example.cpp \
2928
# Empty last line
3029

unit/util/simplify_expr.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests of the expression simplifier
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include <catch.hpp>
10+
11+
#include <util/arith_tools.h>
12+
#include <util/c_types.h>
13+
#include <util/namespace.h>
14+
#include <util/pointer_predicates.h>
15+
#include <util/simplify_expr.h>
16+
#include <util/std_expr.h>
17+
#include <util/symbol_table.h>
18+
19+
TEST_CASE("Simplify pointer_offset(address of array index)")
20+
{
21+
symbol_tablet symbol_table;
22+
namespacet ns(symbol_table);
23+
24+
array_typet array_type(char_type(), from_integer(2, size_type()));
25+
symbol_exprt array("A", array_type);
26+
index_exprt index(array, from_integer(1, index_type()));
27+
address_of_exprt address_of(index);
28+
29+
exprt p_o=pointer_offset(address_of);
30+
31+
exprt simp=simplify_expr(p_o, ns);
32+
33+
REQUIRE(simp.id()==ID_constant);
34+
mp_integer offset_value;
35+
REQUIRE(!to_integer(simp, offset_value));
36+
REQUIRE(offset_value==1);
37+
}
38+
39+
TEST_CASE("Simplify const pointer offset")
40+
{
41+
symbol_tablet symbol_table;
42+
namespacet ns(symbol_table);
43+
44+
// build a numeric constant of some pointer type
45+
constant_exprt number=from_integer(1234, size_type());
46+
number.type()=pointer_type(char_type());
47+
48+
exprt p_o=pointer_offset(number);
49+
50+
exprt simp=simplify_expr(p_o, ns);
51+
52+
REQUIRE(simp.id()==ID_constant);
53+
mp_integer offset_value;
54+
REQUIRE(!to_integer(simp, offset_value));
55+
REQUIRE(offset_value==1234);
56+
}

0 commit comments

Comments
 (0)