Skip to content

Java object factory: retain tagged types #4161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

smowton
Copy link
Contributor

@smowton smowton commented Feb 11, 2019

The object factory used to follow all types, meaning if you asked it for a tagged type you'd get a raw struct type back. This alters the factory to keep the tag (desirable when tags can carry generic information), and adds a unit test verifying that it doesn't strip the tag in some common unusual cases (array, enumeration and generic initialisation).

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.
@smowton
Copy link
Contributor Author

smowton commented Feb 12, 2019

Test-gen bump (https://github.com/diffblue/test-gen/pull/3036) passing

@smowton smowton requested a review from tautschnig February 12, 2019 10:06
Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nice to haves, but otherwise lgtm

if(target_type.id() == ID_struct)
const typet &followed_target_type = ns.follow(target_type);

if(followed_target_type.id() == ID_struct)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ Prefer not directly accessing the id:

if(const auto target_class_type = try_type_dynamic_cast<java_class_type>(followed_target_type))

🦅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the advantage that if we choose to tag java_class_type to differentiate from other struct types, will automatically get checked here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let the id() / dynamic_cast war work itself out in the other thread before doing this on existing code :)

if(subtype.id()==ID_struct)
const typet &subtype = pointer_type.subtype();
const typet &followed_subtype = ns.follow(subtype);
if(followed_subtype.id() == ID_struct)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦅

@@ -1049,9 +1054,9 @@ void java_object_factoryt::gen_nondet_init(
update_in_place,
location);
}
else if(type.id()==ID_struct)
else if(followed_type.id() == ID_struct)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦅


THEN("No raw struct expressions should appear")
{
REQUIRE(!uses_raw_struct_types(created_code));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ REQUIRE_FALSE is a little clearer to read than the ! IMO


THEN("An A, a B and a C object should be allocated")
{
REQUIRE(contains_decl_of_type(created_code, A_type));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 You might like to use require_goto_statements::require_declaration_of_name either here, or inline, or expand it with your functionality.


static bool contains_decl_of_type(const exprt &expr, const typet &type)
{
return contains(expr, [&type](const exprt &subexpr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ Here you do a full tree search of the entire ast for code_decl, but in practise it is only code_blockt you need to flatten? require_goto_statements::get_all_statements does the top level flattening. This has the advantage of not being misleading since a decl can't really appear anywhere in the AST.

}

static bool
contains(const exprt &expr, std::function<bool(const exprt &)> predicate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ Could these be implemented with a depth_begin()/depth_end()? Then can use std::any?

THEN("An HasGeneric, Generic and OtherGeneric object should be allocated")
{
REQUIRE(contains_decl_of_type(created_code, HasGeneric_type));
REQUIRE(contains_decl_with_id(created_code, generic_id));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ I think this name is misleading: I was expecting it to be the identifier of the declaration, rather than the tag of the type, perhaps a better name would be contains_decl_with_struct_tag?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, why do you handle these via just checking tags rather than through the actual type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Laziness -- they're generics so they have decorators (so they're not == to a plain struct_tag_typet). Explained in a comment; I'll leave it to the generics tests to verify the structure of generic types.

Previously if asked to populate a pointer with tagged type (e.g. "Object *") then it would
allocate a "struct Object { ... }", i.e. the struct_typet rather than the struct_tag_typet.
This verifies that it now retains tag types.
@smowton smowton force-pushed the smowton/fix/object-factory-keep-struct-tags branch from 7746d32 to 328bc04 Compare February 12, 2019 11:17
@smowton
Copy link
Contributor Author

smowton commented Feb 12, 2019

Applied some of the nice-to-haves, will merge once CI passes.

@smowton smowton merged commit d5740b3 into diffblue:develop Feb 12, 2019
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: 328bc04).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/100597612

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants