Skip to content

Commit 8f2a82e

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 bbe8cca commit 8f2a82e

7 files changed

+55
-64
lines changed

jbmc/src/java_bytecode/convert_java_nondet.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static goto_programt::targett insert_nondet_init_code(
3636
const goto_programt::targett &target,
3737
symbol_table_baset &symbol_table,
3838
message_handlert &message_handler,
39-
const object_factory_parameterst &object_factory_parameters,
39+
object_factory_parameterst object_factory_parameters,
4040
const irep_idt &mode)
4141
{
4242
// Return if the instruction isn't an assignment
@@ -76,7 +76,8 @@ static goto_programt::targett insert_nondet_init_code(
7676
}
7777

7878
// Check whether the nondet object may be null
79-
const auto nullable=to_side_effect_expr_nondet(side_effect).get_nullable();
79+
if(!to_side_effect_expr_nondet(side_effect).get_nullable())
80+
object_factory_parameters.max_nonnull_tree_depth = 1;
8081
// Get the symbol to nondet-init
8182
const auto source_loc=target->source_location;
8283

@@ -92,7 +93,6 @@ static goto_programt::targett insert_nondet_init_code(
9293
source_loc,
9394
true,
9495
allocation_typet::DYNAMIC,
95-
nullable,
9696
object_factory_parameters,
9797
update_in_placet::NO_UPDATE_IN_PLACE);
9898

jbmc/src/java_bytecode/java_entry_point.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,18 @@ static void java_static_lifetime_init(
217217
if(allow_null && is_non_null_library_global(nameid))
218218
allow_null = false;
219219
}
220+
object_factory_parameterst parameters = object_factory_parameters;
221+
if(!allow_null)
222+
parameters.max_nonnull_tree_depth = 1;
223+
220224
gen_nondet_init(
221225
sym.symbol_expr(),
222226
code_block,
223227
symbol_table,
224228
source_location,
225229
false,
226230
allocation_typet::GLOBAL,
227-
allow_null,
228-
object_factory_parameters,
231+
parameters,
229232
pointer_type_selector,
230233
update_in_placet::NO_UPDATE_IN_PLACE);
231234
}
@@ -299,10 +302,10 @@ exprt::operandst java_build_arguments(
299302
// be null
300303
bool is_this=(param_number==0) && parameters[param_number].get_this();
301304

302-
bool allow_null=
303-
!assume_init_pointers_not_null && !is_main && !is_this;
304-
305305
object_factory_parameterst parameters = object_factory_parameters;
306+
if(assume_init_pointers_not_null || is_main || is_this)
307+
parameters.max_nonnull_tree_depth = 1;
308+
306309
parameters.function_id = goto_functionst::entry_point();
307310

308311
// generate code to allocate and non-deterministicaly initialize the
@@ -311,7 +314,6 @@ exprt::operandst java_build_arguments(
311314
p.type(),
312315
base_name,
313316
init_code,
314-
allow_null,
315317
symbol_table,
316318
parameters,
317319
allocation_typet::LOCAL,

jbmc/src/java_bytecode/java_object_factory.cpp

+15-46
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ class java_object_factoryt
113113
allocation_typet alloc_type,
114114
bool override_,
115115
const typet &override_type,
116-
bool allow_null,
117116
size_t depth,
118117
update_in_placet);
119118

@@ -124,7 +123,6 @@ class java_object_factoryt
124123
const irep_idt &class_identifier,
125124
allocation_typet alloc_type,
126125
const pointer_typet &pointer_type,
127-
bool allow_null,
128126
size_t depth,
129127
const update_in_placet &update_in_place);
130128

@@ -434,7 +432,6 @@ void java_object_factoryt::gen_pointer_target_init(
434432
alloc_type,
435433
false, // override
436434
typet(), // override type immaterial
437-
true, // allow_null always enabled in sub-objects
438435
depth+1,
439436
update_in_place);
440437
}
@@ -717,11 +714,6 @@ static bool add_nondet_string_pointer_initialization(
717714
/// others.
718715
/// \param alloc_type:
719716
/// Allocation type (global, local or dynamic)
720-
/// \param allow_null:
721-
/// true iff the the non-det initialization code is allowed to set null as a
722-
/// value to the pointer \p expr; note that the current value of allow_null is
723-
/// _not_ inherited by subsequent recursive calls; those will always be
724-
/// authorized to assign null to a pointer
725717
/// \param depth:
726718
/// Number of times that a pointer has been dereferenced from the root of the
727719
/// object tree that we are initializing.
@@ -738,7 +730,6 @@ void java_object_factoryt::gen_nondet_pointer_init(
738730
const irep_idt &class_identifier,
739731
allocation_typet alloc_type,
740732
const pointer_typet &pointer_type,
741-
bool allow_null,
742733
size_t depth,
743734
const update_in_placet &update_in_place)
744735
{
@@ -843,7 +834,6 @@ void java_object_factoryt::gen_nondet_pointer_init(
843834
// Note string-type-specific initialization might fail, e.g. if java.lang.CharSequence does not
844835
// have the expected fields (typically this happens if --refine-strings was not passed). In this
845836
// case we fall back to normal pointer target init.
846-
847837
bool string_init_succeeded = false;
848838

849839
if(java_string_library_preprocesst::implements_java_char_sequence_pointer(
@@ -873,6 +863,9 @@ void java_object_factoryt::gen_nondet_pointer_init(
873863

874864
auto set_null_inst=get_null_assignment(expr, pointer_type);
875865

866+
const bool allow_null =
867+
depth > object_factory_parameters.max_nonnull_tree_depth;
868+
876869
// Alternatively, if this is a void* we *must* initialise with null:
877870
// (This can currently happen for some cases of #exception_value)
878871
bool must_be_null=
@@ -977,7 +970,6 @@ symbol_exprt java_object_factoryt::gen_nondet_subtype_pointer_init(
977970
alloc_type,
978971
false, // override
979972
typet(), // override_type
980-
true, // allow_null
981973
depth,
982974
update_in_placet::NO_UPDATE_IN_PLACE);
983975

@@ -1099,7 +1091,6 @@ void java_object_factoryt::gen_nondet_struct_init(
10991091
alloc_type,
11001092
false, // override
11011093
typet(), // override_type
1102-
true, // allow_null always true for sub-objects
11031094
depth,
11041095
substruct_in_place);
11051096
}
@@ -1149,9 +1140,6 @@ void java_object_factoryt::gen_nondet_struct_init(
11491140
/// If true, initialize with `override_type` instead of `expr.type()`. Used at
11501141
/// the moment for reference arrays, which are implemented as void* arrays but
11511142
/// should be init'd as their true type with appropriate casts.
1152-
/// \param allow_null:
1153-
/// True iff the the non-det initialization code is allowed to set null as a
1154-
/// value to a pointer.
11551143
/// \param depth:
11561144
/// Number of times that a pointer has been dereferenced from the root of the
11571145
/// object tree that we are initializing.
@@ -1171,7 +1159,6 @@ void java_object_factoryt::gen_nondet_init(
11711159
allocation_typet alloc_type,
11721160
bool override_,
11731161
const typet &override_type,
1174-
bool allow_null,
11751162
size_t depth,
11761163
update_in_placet update_in_place)
11771164
{
@@ -1198,7 +1185,6 @@ void java_object_factoryt::gen_nondet_init(
11981185
class_identifier,
11991186
alloc_type,
12001187
pointer_type,
1201-
allow_null,
12021188
depth,
12031189
update_in_place);
12041190
}
@@ -1278,14 +1264,13 @@ void java_object_factoryt::allocate_nondet_length_array(
12781264
gen_nondet_init(
12791265
assignments,
12801266
length_sym_expr,
1281-
false, // is_sub
1267+
false, // is_sub
12821268
irep_idt(),
1283-
false, // skip_classid
1269+
false, // skip_classid
12841270
allocation_typet::LOCAL, // immaterial, type is primitive
1285-
false, // override
1286-
typet(), // override type is immaterial
1287-
false, // allow_null
1288-
0, // depth is immaterial
1271+
false, // override
1272+
typet(), // override type is immaterial
1273+
0, // depth is immaterial, always non-null
12891274
update_in_placet::NO_UPDATE_IN_PLACE);
12901275

12911276
// Insert assumptions to bound its length:
@@ -1436,7 +1421,6 @@ void java_object_factoryt::gen_nondet_array_init(
14361421
allocation_typet::DYNAMIC,
14371422
true, // override
14381423
element_type,
1439-
true, // allow_null
14401424
depth,
14411425
child_update_in_place);
14421426

@@ -1486,7 +1470,6 @@ exprt object_factory(
14861470
const typet &type,
14871471
const irep_idt base_name,
14881472
code_blockt &init_code,
1489-
bool allow_null,
14901473
symbol_table_baset &symbol_table,
14911474
const object_factory_parameterst &parameters,
14921475
allocation_typet alloc_type,
@@ -1522,14 +1505,13 @@ exprt object_factory(
15221505
state.gen_nondet_init(
15231506
assignments,
15241507
object,
1525-
false, // is_sub
1526-
"", // class_identifier
1527-
false, // skip_classid
1508+
false, // is_sub
1509+
"", // class_identifier
1510+
false, // skip_classid
15281511
alloc_type,
15291512
false, // override
15301513
typet(), // override_type is immaterial
1531-
allow_null,
1532-
0, // initial depth
1514+
1, // initial depth
15331515
update_in_placet::NO_UPDATE_IN_PLACE);
15341516

15351517
declare_created_symbols(symbols_created, loc, init_code);
@@ -1560,13 +1542,6 @@ exprt object_factory(
15601542
/// \param alloc_type:
15611543
/// Allocate new objects as global objects (GLOBAL) or as local variables
15621544
/// (LOCAL) or using malloc (DYNAMIC).
1563-
/// \param allow_null:
1564-
/// When \p expr is a pointer, the non-det initializing code will
1565-
/// unconditionally set \p expr to a non-null object iff \p allow_null is
1566-
/// true. Note that other references down the object hierarchy *can* be null
1567-
/// when \p allow_null is false (as this parameter is not inherited by
1568-
/// subsequent recursive calls). Has no effect when \p expr is not
1569-
/// pointer-typed.
15701545
/// \param object_factory_parameters:
15711546
/// Parameters for the generation of non deterministic objects.
15721547
/// \param pointer_type_selector:
@@ -1587,7 +1562,6 @@ void gen_nondet_init(
15871562
const source_locationt &loc,
15881563
bool skip_classid,
15891564
allocation_typet alloc_type,
1590-
bool allow_null,
15911565
const object_factory_parameterst &object_factory_parameters,
15921566
const select_pointer_typet &pointer_type_selector,
15931567
update_in_placet update_in_place)
@@ -1604,14 +1578,13 @@ void gen_nondet_init(
16041578
state.gen_nondet_init(
16051579
assignments,
16061580
expr,
1607-
false, // is_sub
1608-
"", // class_identifier
1581+
false, // is_sub
1582+
"", // class_identifier
16091583
skip_classid,
16101584
alloc_type,
16111585
false, // override
16121586
typet(), // override_type is immaterial
1613-
allow_null,
1614-
0, // initial depth
1587+
1, // initial depth
16151588
update_in_place);
16161589

16171590
declare_created_symbols(symbols_created, loc, init_code);
@@ -1624,7 +1597,6 @@ exprt object_factory(
16241597
const typet &type,
16251598
const irep_idt base_name,
16261599
code_blockt &init_code,
1627-
bool allow_null,
16281600
symbol_tablet &symbol_table,
16291601
const object_factory_parameterst &object_factory_parameters,
16301602
allocation_typet alloc_type,
@@ -1635,7 +1607,6 @@ exprt object_factory(
16351607
type,
16361608
base_name,
16371609
init_code,
1638-
allow_null,
16391610
symbol_table,
16401611
object_factory_parameters,
16411612
alloc_type,
@@ -1651,7 +1622,6 @@ void gen_nondet_init(
16511622
const source_locationt &loc,
16521623
bool skip_classid,
16531624
allocation_typet alloc_type,
1654-
bool allow_null,
16551625
const object_factory_parameterst &object_factory_parameters,
16561626
update_in_placet update_in_place)
16571627
{
@@ -1663,7 +1633,6 @@ void gen_nondet_init(
16631633
loc,
16641634
skip_classid,
16651635
alloc_type,
1666-
allow_null,
16671636
object_factory_parameters,
16681637
pointer_type_selector,
16691638
update_in_place);

jbmc/src/java_bytecode/java_object_factory.h

-4
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

jbmc/src/java_bytecode/java_static_initializers.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -781,14 +781,19 @@ codet stub_global_initializer_factoryt::get_stub_initializer_body(
781781
{
782782
const symbol_exprt new_global_symbol =
783783
symbol_table.lookup_ref(it->second).symbol_expr();
784+
785+
parameters.max_nonnull_tree_depth =
786+
is_non_null_library_global(it->second)
787+
? object_factory_parameters.max_nonnull_tree_depth + 1
788+
: object_factory_parameters.max_nonnull_tree_depth;
789+
784790
gen_nondet_init(
785791
new_global_symbol,
786792
static_init_body,
787793
symbol_table,
788794
source_locationt(),
789795
false,
790796
allocation_typet::DYNAMIC,
791-
!is_non_null_library_global(it->second),
792797
parameters,
793798
pointer_type_selector,
794799
update_in_placet::NO_UPDATE_IN_PLACE);

jbmc/src/java_bytecode/object_factory_parameters.h

+13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, [email protected]
1717
#define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5
1818
#define MAX_NONDET_STRING_LENGTH std::numeric_limits<std::int32_t>::max()
1919
#define MAX_NONDET_TREE_DEPTH 5
20+
#define MAX_NONNULL_TREE_DEPTH 0
2021

2122
struct object_factory_parameterst final
2223
{
@@ -34,6 +35,18 @@ struct object_factory_parameterst final
3435
/// such depth becomes >= than this maximum value.
3536
size_t max_nondet_tree_depth=MAX_NONDET_TREE_DEPTH;
3637

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

0 commit comments

Comments
 (0)