Skip to content

Commit c312a18

Browse files
authored
Merge pull request diffblue#4483 from antlechner/antonia/jof-struct-invariants
Add precondition that pointers point to structs in the object factory
2 parents 5b9df9b + 7cada1b commit c312a18

File tree

1 file changed

+35
-49
lines changed

1 file changed

+35
-49
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -221,21 +221,19 @@ void java_object_factoryt::gen_pointer_target_init(
221221

222222
const namespacet ns(symbol_table);
223223
const typet &followed_target_type = ns.follow(target_type);
224+
PRECONDITION(followed_target_type.id() == ID_struct);
224225

225-
if(followed_target_type.id() == ID_struct)
226+
const auto &target_class_type = to_java_class_type(followed_target_type);
227+
if(has_prefix(id2string(target_class_type.get_tag()), "java::array["))
226228
{
227-
const auto &target_class_type = to_java_class_type(followed_target_type);
228-
if(has_prefix(id2string(target_class_type.get_tag()), "java::array["))
229-
{
230-
gen_nondet_array_init(
231-
assignments, expr, depth + 1, update_in_place, location);
229+
gen_nondet_array_init(
230+
assignments, expr, depth + 1, update_in_place, location);
231+
return;
232+
}
233+
if(target_class_type.get_base("java::java.lang.Enum"))
234+
{
235+
if(gen_nondet_enum_init(assignments, expr, target_class_type, location))
232236
return;
233-
}
234-
if(target_class_type.get_base("java::java.lang.Enum"))
235-
{
236-
if(gen_nondet_enum_init(assignments, expr, target_class_type, location))
237-
return;
238-
}
239237
}
240238

241239
// obtain a target pointer to initialize; if in MUST_UPDATE_IN_PLACE mode we
@@ -485,6 +483,9 @@ void java_object_factoryt::gen_nondet_pointer_init(
485483
{
486484
PRECONDITION(expr.type().id()==ID_pointer);
487485
const namespacet ns(symbol_table);
486+
const typet &subtype = pointer_type.subtype();
487+
const typet &followed_subtype = ns.follow(subtype);
488+
PRECONDITION(followed_subtype.id() == ID_struct);
488489
const pointer_typet &replacement_pointer_type =
489490
pointer_type_selector.convert_pointer_type(
490491
pointer_type, generic_parameter_specialization_map, ns);
@@ -518,44 +519,35 @@ void java_object_factoryt::gen_nondet_pointer_init(
518519
// if one is set below.
519520
recursion_set_entryt recursion_set_entry(recursion_set);
520521

521-
// If the pointed value is struct-typed, then we need to prevent the
522-
// possibility of this code to loop infinitely when initializing a data
523-
// structure with recursive types or unbounded depth. We implement two
524-
// mechanisms here. We keep a set of 'types seen', and detect when we perform
525-
// a 2nd visit to the same type. We also detect the depth in the chain of
526-
// (recursive) calls to the methods of this class. The depth counter is
527-
// incremented only when a pointer is deferenced, including pointers to
528-
// arrays.
522+
// We need to prevent the possibility of this code to loop infinitely when
523+
// initializing a data structure with recursive types or unbounded depth. We
524+
// implement two mechanisms here. We keep a set of 'types seen', and
525+
// detect when we perform a 2nd visit to the same type. We also detect the
526+
// depth in the chain of (recursive) calls to the methods of this class.
527+
// The depth counter is incremented only when a pointer is deferenced,
528+
// including pointers to arrays.
529529
//
530530
// When we visit for 2nd time a type AND the maximum depth is exceeded, we set
531531
// the pointer to NULL instead of recursively initializing the struct to which
532532
// it points.
533-
const typet &subtype = pointer_type.subtype();
534-
const typet &followed_subtype = ns.follow(subtype);
535-
if(followed_subtype.id() == ID_struct)
536-
{
537-
const struct_typet &struct_type = to_struct_type(followed_subtype);
538-
const irep_idt &struct_tag=struct_type.get_tag();
533+
const struct_typet &struct_type = to_struct_type(followed_subtype);
534+
const irep_idt &struct_tag = struct_type.get_tag();
539535

540-
// If this is a recursive type of some kind AND the depth is exceeded, set
541-
// the pointer to null.
542-
if(!recursion_set_entry.insert_entry(struct_tag) &&
543-
depth>=object_factory_parameters.max_nondet_tree_depth)
536+
// If this is a recursive type of some kind AND the depth is exceeded, set
537+
// the pointer to null.
538+
if(
539+
!recursion_set_entry.insert_entry(struct_tag) &&
540+
depth >= object_factory_parameters.max_nondet_tree_depth)
541+
{
542+
if(update_in_place == update_in_placet::NO_UPDATE_IN_PLACE)
544543
{
545-
if(update_in_place==update_in_placet::NO_UPDATE_IN_PLACE)
546-
{
547-
assignments.add(
548-
code_assignt{expr, null_pointer_exprt{pointer_type}, location});
549-
}
550-
// Otherwise leave it as it is.
551-
return;
544+
assignments.add(
545+
code_assignt{expr, null_pointer_exprt{pointer_type}, location});
552546
}
547+
// Otherwise leave it as it is.
548+
return;
553549
}
554550

555-
// If this is a void* we *must* initialise with null:
556-
// (This can currently happen for some cases of #exception_value)
557-
bool must_be_null = subtype == java_void_type();
558-
559551
// If we may be about to initialize a non-null enum type, always run the
560552
// clinit_wrapper of its class first.
561553
// TODO: TG-4689 we may want to do this for all types, not just enums, as
@@ -575,7 +567,7 @@ void java_object_factoryt::gen_nondet_pointer_init(
575567
const auto class_type =
576568
type_try_dynamic_cast<java_class_typet>(followed_subtype))
577569
{
578-
if(class_type->get_base("java::java.lang.Enum") && !must_be_null)
570+
if(class_type->get_base("java::java.lang.Enum"))
579571
{
580572
const irep_idt &class_name = class_type->get_name();
581573
const irep_idt class_clinit = clinit_wrapper_name(class_name);
@@ -630,13 +622,7 @@ void java_object_factoryt::gen_nondet_pointer_init(
630622

631623
const bool allow_null = depth > object_factory_parameters.min_null_tree_depth;
632624

633-
if(must_be_null)
634-
{
635-
// Add the following code to assignments:
636-
// <expr> = nullptr;
637-
new_object_assignments.add(set_null_inst);
638-
}
639-
else if(!allow_null)
625+
if(!allow_null)
640626
{
641627
// Add the following code to assignments:
642628
// <expr> = <aoe>;

0 commit comments

Comments
 (0)