Skip to content

Commit 7cada1b

Browse files
Antonia LechnerAntonia Lechner
Antonia Lechner
authored and
Antonia Lechner
committed
Add precondition that pointers point to structs
It looks like this previously wasn't possible because of void* types of exceptions. But exceptions are now handled differently and not nondet- initialized any more, so it should be safe to add the precondition.
1 parent b2d0d2c commit 7cada1b

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)