Skip to content

Commit 91aa783

Browse files
Generalize allow_null to max_nonnull_tree_depth
allow_null only considered the immediate pointer, but did not allow forcing sub-objects to be non-null. This is required for example to ensure the array elements of the argument to the main() functio to be non-null. The depth argument starts from 1 now to allow the immediate pointer to be maybe null when max_nonnull_tree_depth is 0.
1 parent 3bd1eb3 commit 91aa783

File tree

5 files changed

+56
-51
lines changed

5 files changed

+56
-51
lines changed

src/goto-programs/convert_nondet.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static goto_programt::targett insert_nondet_init_code(
3434
const goto_programt::targett &target,
3535
symbol_table_baset &symbol_table,
3636
message_handlert &message_handler,
37-
const object_factory_parameterst &object_factory_parameters)
37+
object_factory_parameterst object_factory_parameters)
3838
{
3939
// Return if the instruction isn't an assignment
4040
const auto next_instr=std::next(target);
@@ -73,7 +73,8 @@ static goto_programt::targett insert_nondet_init_code(
7373
}
7474

7575
// Check whether the nondet object may be null
76-
const auto nullable=to_side_effect_expr_nondet(side_effect).get_nullable();
76+
if(!to_side_effect_expr_nondet(side_effect).get_nullable())
77+
object_factory_parameters.max_nonnull_tree_depth = 1;
7778
// Get the symbol to nondet-init
7879
const auto source_loc=target->source_location;
7980

@@ -89,7 +90,6 @@ static goto_programt::targett insert_nondet_init_code(
8990
source_loc,
9091
true,
9192
allocation_typet::DYNAMIC,
92-
nullable,
9393
object_factory_parameters,
9494
update_in_placet::NO_UPDATE_IN_PLACE);
9595

src/java_bytecode/java_bytecode_language.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,50 @@ Author: Daniel Kroening, [email protected]
5959
" the purpose of lazy method loading\n" /* NOLINT(*) */ \
6060
" A '.*' wildcard is allowed to specify all class members\n"
6161

62+
#define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5
63+
#define MAX_NONDET_STRING_LENGTH std::numeric_limits<std::int32_t>::max()
64+
#define MAX_NONDET_TREE_DEPTH 5
65+
#define MAX_NONNULL_TREE_DEPTH 0
66+
6267
class symbolt;
6368

6469
enum lazy_methods_modet
6570
{
6671
LAZY_METHODS_MODE_EAGER,
6772
LAZY_METHODS_MODE_CONTEXT_INSENSITIVE,
68-
LAZY_METHODS_MODE_EXTERNAL_DRIVER
73+
LAZY_METHODS_MODE_CONTEXT_SENSITIVE
74+
};
75+
76+
struct object_factory_parameterst final
77+
{
78+
/// Maximum value for the non-deterministically-chosen length of an array.
79+
size_t max_nondet_array_length=MAX_NONDET_ARRAY_LENGTH_DEFAULT;
80+
81+
/// Maximum value for the non-deterministically-chosen length of a string.
82+
size_t max_nondet_string_length=MAX_NONDET_STRING_LENGTH;
83+
84+
/// Maximum depth for object hierarchy on input.
85+
/// Used to prevent object factory to loop infinitely during the
86+
/// generation of code that allocates/initializes data structures of recursive
87+
/// data types or unbounded depth. We bound the maximum number of times we
88+
/// dereference a pointer using a 'depth counter'. We set a pointer to null if
89+
/// such depth becomes >= than this maximum value.
90+
size_t max_nondet_tree_depth=MAX_NONDET_TREE_DEPTH;
91+
92+
/// To force a certain depth of non-null objects.
93+
/// The default is that objects are 'maybe null' up to the nondet tree depth.
94+
/// Examples:
95+
/// * max_nondet_tree_depth=0, max_nonnull_tree_depth irrelevant
96+
/// pointer initialized to null
97+
/// * max_nondet_tree_depth=n, max_nonnull_tree_depth=0
98+
/// pointer and children up to depth n maybe-null, beyond n null
99+
/// * max_nondet_tree_depth=n >=m, max_nonnull_tree_depth=m
100+
/// pointer and children up to depth m initialized to non-null,
101+
/// children up to n maybe-null, beyond n null
102+
size_t max_nonnull_tree_depth=MAX_NONNULL_TREE_DEPTH;
103+
104+
/// Force string content to be ASCII printable characters when set to true.
105+
bool string_printable = false;
69106
};
70107

71108
class java_bytecode_languaget:public languaget

src/java_bytecode/java_entry_point.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,18 @@ static void java_static_lifetime_init(
120120
if(allow_null && is_non_null_library_global(nameid))
121121
allow_null = false;
122122
}
123+
object_factory_parameterst parameters = object_factory_parameters;
124+
if(!allow_null)
125+
parameters.max_nonnull_tree_depth = 1;
126+
123127
gen_nondet_init(
124128
sym.symbol_expr(),
125129
code_block,
126130
symbol_table,
127131
source_location,
128132
false,
129133
allocation_typet::GLOBAL,
130-
allow_null,
131-
object_factory_parameters,
134+
parameters,
132135
pointer_type_selector,
133136
update_in_placet::NO_UPDATE_IN_PLACE);
134137
}
@@ -202,8 +205,9 @@ exprt::operandst java_build_arguments(
202205
// be null
203206
bool is_this=(param_number==0) && parameters[param_number].get_this();
204207

205-
bool allow_null=
206-
!assume_init_pointers_not_null && !is_main && !is_this;
208+
object_factory_parameterst parameters = object_factory_parameters;
209+
if(assume_init_pointers_not_null || is_main || is_this)
210+
parameters.max_nonnull_tree_depth = 1;
207211

208212
// generate code to allocate and non-deterministicaly initialize the
209213
// argument
@@ -212,9 +216,8 @@ exprt::operandst java_build_arguments(
212216
p.type(),
213217
base_name,
214218
init_code,
215-
allow_null,
216219
symbol_table,
217-
object_factory_parameters,
220+
parameters,
218221
allocation_typet::LOCAL,
219222
function.location,
220223
pointer_type_selector);

src/java_bytecode/java_object_factory.cpp

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ class java_object_factoryt
144144
allocation_typet alloc_type,
145145
bool override_,
146146
const typet &override_type,
147-
bool allow_null,
148147
size_t depth,
149148
update_in_placet);
150149

@@ -155,7 +154,6 @@ class java_object_factoryt
155154
const irep_idt &class_identifier,
156155
allocation_typet alloc_type,
157156
const pointer_typet &pointer_type,
158-
bool allow_null,
159157
size_t depth,
160158
const update_in_placet &update_in_place);
161159

@@ -452,7 +450,6 @@ void java_object_factoryt::gen_pointer_target_init(
452450
alloc_type,
453451
false, // override
454452
typet(), // override type immaterial
455-
true, // allow_null always enabled in sub-objects
456453
depth+1,
457454
update_in_place);
458455
}
@@ -727,11 +724,6 @@ static bool add_nondet_string_pointer_initialization(
727724
/// others.
728725
/// \param alloc_type:
729726
/// Allocation type (global, local or dynamic)
730-
/// \param allow_null:
731-
/// true iff the the non-det initialization code is allowed to set null as a
732-
/// value to the pointer \p expr; note that the current value of allow_null is
733-
/// _not_ inherited by subsequent recursive calls; those will always be
734-
/// authorized to assign null to a pointer
735727
/// \param depth:
736728
/// Number of times that a pointer has been dereferenced from the root of the
737729
/// object tree that we are initializing.
@@ -748,7 +740,6 @@ void java_object_factoryt::gen_nondet_pointer_init(
748740
const irep_idt &class_identifier,
749741
allocation_typet alloc_type,
750742
const pointer_typet &pointer_type,
751-
bool allow_null,
752743
size_t depth,
753744
const update_in_placet &update_in_place)
754745
{
@@ -870,7 +861,9 @@ void java_object_factoryt::gen_nondet_pointer_init(
870861

871862
// Determine whether the pointer can be null. In particular the pointers
872863
// inside the java.lang.Class class shall not be null
873-
const bool not_null = !allow_null || class_identifier == "java.lang.Class";
864+
const bool not_null =
865+
depth <= object_factory_parameters.max_nonnull_tree_depth ||
866+
class_identifier == "java.lang.Class";
874867

875868
// Alternatively, if this is a void* we *must* initialise with null:
876869
// (This can currently happen for some cases of #exception_value)
@@ -970,7 +963,6 @@ symbol_exprt java_object_factoryt::gen_nondet_subtype_pointer_init(
970963
alloc_type,
971964
false, // override
972965
typet(), // override_type
973-
true, // allow_null
974966
depth,
975967
update_in_placet::NO_UPDATE_IN_PLACE);
976968

@@ -1079,7 +1071,6 @@ void java_object_factoryt::gen_nondet_struct_init(
10791071
alloc_type,
10801072
false, // override
10811073
typet(), // override_type
1082-
true, // allow_null always true for sub-objects
10831074
depth,
10841075
substruct_in_place);
10851076
}
@@ -1129,9 +1120,6 @@ void java_object_factoryt::gen_nondet_struct_init(
11291120
/// If true, initialize with `override_type` instead of `expr.type()`. Used at
11301121
/// the moment for reference arrays, which are implemented as void* arrays but
11311122
/// should be init'd as their true type with appropriate casts.
1132-
/// \param allow_null:
1133-
/// True iff the the non-det initialization code is allowed to set null as a
1134-
/// value to a pointer.
11351123
/// \param depth:
11361124
/// Number of times that a pointer has been dereferenced from the root of the
11371125
/// object tree that we are initializing.
@@ -1151,7 +1139,6 @@ void java_object_factoryt::gen_nondet_init(
11511139
allocation_typet alloc_type,
11521140
bool override_,
11531141
const typet &override_type,
1154-
bool allow_null,
11551142
size_t depth,
11561143
update_in_placet update_in_place)
11571144
{
@@ -1178,7 +1165,6 @@ void java_object_factoryt::gen_nondet_init(
11781165
class_identifier,
11791166
alloc_type,
11801167
pointer_type,
1181-
allow_null,
11821168
depth,
11831169
update_in_place);
11841170
}
@@ -1262,8 +1248,7 @@ void java_object_factoryt::allocate_nondet_length_array(
12621248
allocation_typet::LOCAL, // immaterial, type is primitive
12631249
false, // override
12641250
typet(), // override type is immaterial
1265-
false, // allow_null
1266-
0, // depth is immaterial
1251+
0, // depth is immaterial, always non-null
12671252
update_in_placet::NO_UPDATE_IN_PLACE);
12681253

12691254
// Insert assumptions to bound its length:
@@ -1410,7 +1395,6 @@ void java_object_factoryt::gen_nondet_array_init(
14101395
allocation_typet::DYNAMIC,
14111396
true, // override
14121397
element_type,
1413-
true, // allow_null
14141398
depth,
14151399
child_update_in_place);
14161400

@@ -1460,7 +1444,6 @@ exprt object_factory(
14601444
const typet &type,
14611445
const irep_idt base_name,
14621446
code_blockt &init_code,
1463-
bool allow_null,
14641447
symbol_table_baset &symbol_table,
14651448
const object_factory_parameterst &parameters,
14661449
allocation_typet alloc_type,
@@ -1502,8 +1485,7 @@ exprt object_factory(
15021485
alloc_type,
15031486
false, // override
15041487
typet(), // override_type is immaterial
1505-
allow_null,
1506-
0, // initial depth
1488+
1, // initial depth
15071489
update_in_placet::NO_UPDATE_IN_PLACE);
15081490

15091491
declare_created_symbols(symbols_created, loc, init_code);
@@ -1534,13 +1516,6 @@ exprt object_factory(
15341516
/// \param alloc_type:
15351517
/// Allocate new objects as global objects (GLOBAL) or as local variables
15361518
/// (LOCAL) or using malloc (DYNAMIC).
1537-
/// \param allow_null:
1538-
/// When \p expr is a pointer, the non-det initializing code will
1539-
/// unconditionally set \p expr to a non-null object iff \p allow_null is
1540-
/// true. Note that other references down the object hierarchy *can* be null
1541-
/// when \p allow_null is false (as this parameter is not inherited by
1542-
/// subsequent recursive calls). Has no effect when \p expr is not
1543-
/// pointer-typed.
15441519
/// \param object_factory_parameters:
15451520
/// Parameters for the generation of non deterministic objects.
15461521
/// \param pointer_type_selector:
@@ -1561,7 +1536,6 @@ void gen_nondet_init(
15611536
const source_locationt &loc,
15621537
bool skip_classid,
15631538
allocation_typet alloc_type,
1564-
bool allow_null,
15651539
const object_factory_parameterst &object_factory_parameters,
15661540
const select_pointer_typet &pointer_type_selector,
15671541
update_in_placet update_in_place)
@@ -1584,8 +1558,7 @@ void gen_nondet_init(
15841558
alloc_type,
15851559
false, // override
15861560
typet(), // override_type is immaterial
1587-
allow_null,
1588-
0, // initial depth
1561+
1, // initial depth
15891562
update_in_place);
15901563

15911564
declare_created_symbols(symbols_created, loc, init_code);
@@ -1598,7 +1571,6 @@ exprt object_factory(
15981571
const typet &type,
15991572
const irep_idt base_name,
16001573
code_blockt &init_code,
1601-
bool allow_null,
16021574
symbol_tablet &symbol_table,
16031575
const object_factory_parameterst &object_factory_parameters,
16041576
allocation_typet alloc_type,
@@ -1609,7 +1581,6 @@ exprt object_factory(
16091581
type,
16101582
base_name,
16111583
init_code,
1612-
allow_null,
16131584
symbol_table,
16141585
object_factory_parameters,
16151586
alloc_type,
@@ -1625,7 +1596,6 @@ void gen_nondet_init(
16251596
const source_locationt &loc,
16261597
bool skip_classid,
16271598
allocation_typet alloc_type,
1628-
bool allow_null,
16291599
const object_factory_parameterst &object_factory_parameters,
16301600
update_in_placet update_in_place)
16311601
{
@@ -1637,7 +1607,6 @@ void gen_nondet_init(
16371607
loc,
16381608
skip_classid,
16391609
alloc_type,
1640-
allow_null,
16411610
object_factory_parameters,
16421611
pointer_type_selector,
16431612
update_in_place);

src/java_bytecode/java_object_factory.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ exprt object_factory(
9090
const typet &type,
9191
const irep_idt base_name,
9292
code_blockt &init_code,
93-
bool allow_null,
9493
symbol_table_baset &symbol_table,
9594
const object_factory_parameterst &parameters,
9695
allocation_typet alloc_type,
@@ -101,7 +100,6 @@ exprt object_factory(
101100
const typet &type,
102101
const irep_idt base_name,
103102
code_blockt &init_code,
104-
bool allow_null,
105103
symbol_tablet &symbol_table,
106104
const object_factory_parameterst &object_factory_parameters,
107105
allocation_typet alloc_type,
@@ -121,7 +119,6 @@ void gen_nondet_init(
121119
const source_locationt &loc,
122120
bool skip_classid,
123121
allocation_typet alloc_type,
124-
bool allow_null,
125122
const object_factory_parameterst &object_factory_parameters,
126123
const select_pointer_typet &pointer_type_selector,
127124
update_in_placet update_in_place);
@@ -133,7 +130,6 @@ void gen_nondet_init(
133130
const source_locationt &loc,
134131
bool skip_classid,
135132
allocation_typet alloc_type,
136-
bool allow_null,
137133
const object_factory_parameterst &object_factory_parameters,
138134
update_in_placet update_in_place);
139135

0 commit comments

Comments
 (0)