Skip to content

Commit 229964c

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() function 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 5ab7d60 commit 229964c

File tree

6 files changed

+52
-70
lines changed

6 files changed

+52
-70
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_entry_point.cpp

Lines changed: 17 additions & 15 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,22 +205,21 @@ 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
210-
main_arguments[param_number]=
211-
object_factory(
212-
p.type(),
213-
base_name,
214-
init_code,
215-
allow_null,
216-
symbol_table,
217-
object_factory_parameters,
218-
allocation_typet::LOCAL,
219-
function.location,
220-
pointer_type_selector);
214+
main_arguments[param_number] = object_factory(
215+
p.type(),
216+
base_name,
217+
init_code,
218+
symbol_table,
219+
parameters,
220+
allocation_typet::LOCAL,
221+
function.location,
222+
pointer_type_selector);
221223

222224
// record as an input
223225
codet input(ID_input);

src/java_bytecode/java_object_factory.cpp

Lines changed: 15 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ class java_object_factoryt
133133
allocation_typet alloc_type,
134134
bool override_,
135135
const typet &override_type,
136-
bool allow_null,
137136
size_t depth,
138137
update_in_placet);
139138

@@ -144,7 +143,6 @@ class java_object_factoryt
144143
const irep_idt &class_identifier,
145144
allocation_typet alloc_type,
146145
const pointer_typet &pointer_type,
147-
bool allow_null,
148146
size_t depth,
149147
const update_in_placet &update_in_place);
150148

@@ -441,7 +439,6 @@ void java_object_factoryt::gen_pointer_target_init(
441439
alloc_type,
442440
false, // override
443441
typet(), // override type immaterial
444-
true, // allow_null always enabled in sub-objects
445442
depth+1,
446443
update_in_place);
447444
}
@@ -716,11 +713,6 @@ static bool add_nondet_string_pointer_initialization(
716713
/// others.
717714
/// \param alloc_type:
718715
/// Allocation type (global, local or dynamic)
719-
/// \param allow_null:
720-
/// true iff the the non-det initialization code is allowed to set null as a
721-
/// value to the pointer \p expr; note that the current value of allow_null is
722-
/// _not_ inherited by subsequent recursive calls; those will always be
723-
/// authorized to assign null to a pointer
724716
/// \param depth:
725717
/// Number of times that a pointer has been dereferenced from the root of the
726718
/// object tree that we are initializing.
@@ -737,7 +729,6 @@ void java_object_factoryt::gen_nondet_pointer_init(
737729
const irep_idt &class_identifier,
738730
allocation_typet alloc_type,
739731
const pointer_typet &pointer_type,
740-
bool allow_null,
741732
size_t depth,
742733
const update_in_placet &update_in_place)
743734
{
@@ -858,7 +849,9 @@ void java_object_factoryt::gen_nondet_pointer_init(
858849

859850
// Determine whether the pointer can be null. In particular the pointers
860851
// inside the java.lang.Class class shall not be null
861-
const bool not_null = !allow_null || class_identifier == "java.lang.Class";
852+
const bool not_null =
853+
depth <= object_factory_parameters.max_nonnull_tree_depth ||
854+
class_identifier == "java.lang.Class";
862855

863856
// Alternatively, if this is a void* we *must* initialise with null:
864857
// (This can currently happen for some cases of #exception_value)
@@ -958,7 +951,6 @@ symbol_exprt java_object_factoryt::gen_nondet_subtype_pointer_init(
958951
alloc_type,
959952
false, // override
960953
typet(), // override_type
961-
true, // allow_null
962954
depth,
963955
update_in_placet::NO_UPDATE_IN_PLACE);
964956

@@ -1067,7 +1059,6 @@ void java_object_factoryt::gen_nondet_struct_init(
10671059
alloc_type,
10681060
false, // override
10691061
typet(), // override_type
1070-
true, // allow_null always true for sub-objects
10711062
depth,
10721063
substruct_in_place);
10731064
}
@@ -1117,9 +1108,6 @@ void java_object_factoryt::gen_nondet_struct_init(
11171108
/// If true, initialize with `override_type` instead of `expr.type()`. Used at
11181109
/// the moment for reference arrays, which are implemented as void* arrays but
11191110
/// should be init'd as their true type with appropriate casts.
1120-
/// \param allow_null:
1121-
/// True iff the the non-det initialization code is allowed to set null as a
1122-
/// value to a pointer.
11231111
/// \param depth:
11241112
/// Number of times that a pointer has been dereferenced from the root of the
11251113
/// object tree that we are initializing.
@@ -1139,7 +1127,6 @@ void java_object_factoryt::gen_nondet_init(
11391127
allocation_typet alloc_type,
11401128
bool override_,
11411129
const typet &override_type,
1142-
bool allow_null,
11431130
size_t depth,
11441131
update_in_placet update_in_place)
11451132
{
@@ -1157,7 +1144,6 @@ void java_object_factoryt::gen_nondet_init(
11571144
class_identifier,
11581145
alloc_type,
11591146
pointer_type,
1160-
allow_null,
11611147
depth,
11621148
update_in_place);
11631149
}
@@ -1220,14 +1206,13 @@ void java_object_factoryt::allocate_nondet_length_array(
12201206
gen_nondet_init(
12211207
assignments,
12221208
length_sym_expr,
1223-
false, // is_sub
1209+
false, // is_sub
12241210
irep_idt(),
1225-
false, // skip_classid
1211+
false, // skip_classid
12261212
allocation_typet::LOCAL, // immaterial, type is primitive
1227-
false, // override
1228-
typet(), // override type is immaterial
1229-
false, // allow_null
1230-
0, // depth is immaterial
1213+
false, // override
1214+
typet(), // override type is immaterial
1215+
0, // depth is immaterial, always non-null
12311216
update_in_placet::NO_UPDATE_IN_PLACE);
12321217

12331218
// Insert assumptions to bound its length:
@@ -1374,7 +1359,6 @@ void java_object_factoryt::gen_nondet_array_init(
13741359
allocation_typet::DYNAMIC,
13751360
true, // override
13761361
element_type,
1377-
true, // allow_null
13781362
depth,
13791363
child_update_in_place);
13801364

@@ -1424,7 +1408,6 @@ exprt object_factory(
14241408
const typet &type,
14251409
const irep_idt base_name,
14261410
code_blockt &init_code,
1427-
bool allow_null,
14281411
symbol_table_baset &symbol_table,
14291412
const object_factory_parameterst &parameters,
14301413
allocation_typet alloc_type,
@@ -1460,14 +1443,13 @@ exprt object_factory(
14601443
state.gen_nondet_init(
14611444
assignments,
14621445
object,
1463-
false, // is_sub
1464-
"", // class_identifier
1465-
false, // skip_classid
1446+
false, // is_sub
1447+
"", // class_identifier
1448+
false, // skip_classid
14661449
alloc_type,
14671450
false, // override
14681451
typet(), // override_type is immaterial
1469-
allow_null,
1470-
0, // initial depth
1452+
1, // initial depth
14711453
update_in_placet::NO_UPDATE_IN_PLACE);
14721454

14731455
declare_created_symbols(symbols_created, loc, init_code);
@@ -1498,13 +1480,6 @@ exprt object_factory(
14981480
/// \param alloc_type:
14991481
/// Allocate new objects as global objects (GLOBAL) or as local variables
15001482
/// (LOCAL) or using malloc (DYNAMIC).
1501-
/// \param allow_null:
1502-
/// When \p expr is a pointer, the non-det initializing code will
1503-
/// unconditionally set \p expr to a non-null object iff \p allow_null is
1504-
/// true. Note that other references down the object hierarchy *can* be null
1505-
/// when \p allow_null is false (as this parameter is not inherited by
1506-
/// subsequent recursive calls). Has no effect when \p expr is not
1507-
/// pointer-typed.
15081483
/// \param object_factory_parameters:
15091484
/// Parameters for the generation of non deterministic objects.
15101485
/// \param pointer_type_selector:
@@ -1525,7 +1500,6 @@ void gen_nondet_init(
15251500
const source_locationt &loc,
15261501
bool skip_classid,
15271502
allocation_typet alloc_type,
1528-
bool allow_null,
15291503
const object_factory_parameterst &object_factory_parameters,
15301504
const select_pointer_typet &pointer_type_selector,
15311505
update_in_placet update_in_place)
@@ -1542,14 +1516,13 @@ void gen_nondet_init(
15421516
state.gen_nondet_init(
15431517
assignments,
15441518
expr,
1545-
false, // is_sub
1546-
"", // class_identifier
1519+
false, // is_sub
1520+
"", // class_identifier
15471521
skip_classid,
15481522
alloc_type,
15491523
false, // override
15501524
typet(), // override_type is immaterial
1551-
allow_null,
1552-
0, // initial depth
1525+
1, // initial depth
15531526
update_in_place);
15541527

15551528
declare_created_symbols(symbols_created, loc, init_code);
@@ -1562,7 +1535,6 @@ exprt object_factory(
15621535
const typet &type,
15631536
const irep_idt base_name,
15641537
code_blockt &init_code,
1565-
bool allow_null,
15661538
symbol_tablet &symbol_table,
15671539
const object_factory_parameterst &object_factory_parameters,
15681540
allocation_typet alloc_type,
@@ -1573,7 +1545,6 @@ exprt object_factory(
15731545
type,
15741546
base_name,
15751547
init_code,
1576-
allow_null,
15771548
symbol_table,
15781549
object_factory_parameters,
15791550
alloc_type,
@@ -1589,7 +1560,6 @@ void gen_nondet_init(
15891560
const source_locationt &loc,
15901561
bool skip_classid,
15911562
allocation_typet alloc_type,
1592-
bool allow_null,
15931563
const object_factory_parameterst &object_factory_parameters,
15941564
update_in_placet update_in_place)
15951565
{
@@ -1601,7 +1571,6 @@ void gen_nondet_init(
16011571
loc,
16021572
skip_classid,
16031573
alloc_type,
1604-
allow_null,
16051574
object_factory_parameters,
16061575
pointer_type_selector,
16071576
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

src/java_bytecode/java_static_initializers.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,17 @@ codet stub_global_initializer_factoryt::get_stub_initializer_body(
373373
{
374374
const symbol_exprt new_global_symbol =
375375
symbol_table.lookup_ref(it->second).symbol_expr();
376+
object_factory_parameterst parameters = object_factory_parameters;
377+
if(is_non_null_library_global(it->second))
378+
parameters.max_nonnull_tree_depth = 1;
376379
gen_nondet_init(
377380
new_global_symbol,
378381
static_init_body,
379382
symbol_table,
380383
source_locationt(),
381384
false,
382385
allocation_typet::DYNAMIC,
383-
!is_non_null_library_global(it->second),
384-
object_factory_parameters,
386+
parameters,
385387
pointer_type_selector,
386388
update_in_placet::NO_UPDATE_IN_PLACE);
387389
}

src/java_bytecode/object_factory_parameters.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5
1616
#define MAX_NONDET_STRING_LENGTH std::numeric_limits<std::int32_t>::max()
1717
#define MAX_NONDET_TREE_DEPTH 5
18+
#define MAX_NONNULL_TREE_DEPTH 0
1819

1920
struct object_factory_parameterst final
2021
{
@@ -32,6 +33,18 @@ struct object_factory_parameterst final
3233
/// such depth becomes >= than this maximum value.
3334
size_t max_nondet_tree_depth=MAX_NONDET_TREE_DEPTH;
3435

36+
/// To force a certain depth of non-null objects.
37+
/// The default is that objects are 'maybe null' up to the nondet tree depth.
38+
/// Examples:
39+
/// * max_nondet_tree_depth=0, max_nonnull_tree_depth irrelevant
40+
/// pointer initialized to null
41+
/// * max_nondet_tree_depth=n, max_nonnull_tree_depth=0
42+
/// pointer and children up to depth n maybe-null, beyond n null
43+
/// * max_nondet_tree_depth=n >=m, max_nonnull_tree_depth=m
44+
/// pointer and children up to depth m initialized to non-null,
45+
/// children up to n maybe-null, beyond n null
46+
size_t max_nonnull_tree_depth = MAX_NONNULL_TREE_DEPTH;
47+
3548
/// Force string content to be ASCII printable characters when set to true.
3649
bool string_printable = false;
3750
};

0 commit comments

Comments
 (0)