Skip to content

Commit 2ecdc0e

Browse files
committed
Object factory: retain type tags
Previously it would follow types as it went, resulting in generated objects with raw struct types. Now it only follows types locally for reference, and passes the tagged types to subroutines.
1 parent d11c3f7 commit 2ecdc0e

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,11 @@ void java_object_factoryt::gen_pointer_target_init(
249249
PRECONDITION(expr.type().id() == ID_pointer);
250250
PRECONDITION(update_in_place != update_in_placet::MAY_UPDATE_IN_PLACE);
251251

252-
if(target_type.id() == ID_struct)
252+
const typet &followed_target_type = ns.follow(target_type);
253+
254+
if(followed_target_type.id() == ID_struct)
253255
{
254-
const auto &target_class_type = to_java_class_type(target_type);
256+
const auto &target_class_type = to_java_class_type(followed_target_type);
255257
if(has_prefix(id2string(target_class_type.get_tag()), "java::array["))
256258
{
257259
gen_nondet_array_init(
@@ -565,10 +567,11 @@ void java_object_factoryt::gen_nondet_pointer_init(
565567
// When we visit for 2nd time a type AND the maximum depth is exceeded, we set
566568
// the pointer to NULL instead of recursively initializing the struct to which
567569
// it points.
568-
const typet &subtype=ns.follow(pointer_type.subtype());
569-
if(subtype.id()==ID_struct)
570+
const typet &subtype = pointer_type.subtype();
571+
const typet &followed_subtype = ns.follow(subtype);
572+
if(followed_subtype.id() == ID_struct)
570573
{
571-
const struct_typet &struct_type=to_struct_type(subtype);
574+
const struct_typet &struct_type = to_struct_type(followed_subtype);
572575
const irep_idt &struct_tag=struct_type.get_tag();
573576

574577
// If this is a recursive type of some kind AND the depth is exceeded, set
@@ -604,7 +607,9 @@ void java_object_factoryt::gen_nondet_pointer_init(
604607
// decide to do this for all types, we should do it here.
605608
// Note also that this logic is mirrored in
606609
// ci_lazy_methodst::initialize_instantiated_classes.
607-
if(const auto class_type = type_try_dynamic_cast<java_class_typet>(subtype))
610+
if(
611+
const auto class_type =
612+
type_try_dynamic_cast<java_class_typet>(followed_subtype))
608613
{
609614
if(class_type->get_base("java::java.lang.Enum") && !must_be_null)
610615
{
@@ -1024,8 +1029,8 @@ void java_object_factoryt::gen_nondet_init(
10241029
update_in_placet update_in_place,
10251030
const source_locationt &location)
10261031
{
1027-
const typet &type = override_type.has_value() ? ns.follow(*override_type)
1028-
: ns.follow(expr.type());
1032+
const typet &type = override_type.has_value() ? *override_type : expr.type();
1033+
const typet &followed_type = ns.follow(type);
10291034

10301035
if(type.id()==ID_pointer)
10311036
{
@@ -1049,9 +1054,9 @@ void java_object_factoryt::gen_nondet_init(
10491054
update_in_place,
10501055
location);
10511056
}
1052-
else if(type.id()==ID_struct)
1057+
else if(followed_type.id() == ID_struct)
10531058
{
1054-
const struct_typet struct_type=to_struct_type(type);
1059+
const struct_typet struct_type = to_struct_type(followed_type);
10551060

10561061
// If we are about to initialize a generic class (as a superclass object
10571062
// for a different object), add its concrete types to the map and delete

jbmc/unit/java-testing-utils/require_goto_statements.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ const irep_idt &require_goto_statements::require_struct_component_assignment(
315315
const std::vector<codet> &entry_point_instructions,
316316
const symbol_tablet &symbol_table)
317317
{
318+
namespacet ns(symbol_table);
319+
318320
// First we need to find the assignments to the component belonging to
319321
// the structure_name object
320322
const auto &component_assignments =
@@ -361,14 +363,13 @@ const irep_idt &require_goto_statements::require_struct_component_assignment(
361363
// After we have found the declaration of the final assignment's
362364
// right hand side, then we want to identify that the type
363365
// is the one we expect, e.g.:
364-
// struct java.lang.Integer { __CPROVER_string @class_identifier; }
365-
// tmp_object_factory$2;
366+
// struct java.lang.Integer tmp_object_factory$2;
366367
const auto &component_declaration =
367368
require_goto_statements::require_declaration_of_name(
368369
component_tmp_name, entry_point_instructions);
369-
REQUIRE(component_declaration.symbol().type().id() == ID_struct);
370+
REQUIRE(component_declaration.symbol().type().id() == ID_struct_tag);
370371
const auto &component_struct =
371-
to_struct_type(component_declaration.symbol().type());
372+
ns.follow_tag(to_struct_tag_type(component_declaration.symbol().type()));
372373
REQUIRE(component_struct.get(ID_name) == component_type_name);
373374

374375
return component_tmp_name;

0 commit comments

Comments
 (0)