Skip to content

Make failed nondet Enum assignment non-fatal #4287

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
merged 3 commits into from
Mar 15, 2019

Conversation

smowton
Copy link
Contributor

@smowton smowton commented Feb 27, 2019

Previously we always expected an Enum type's VALUES array to be present if it may be created in a
stub method. However while this is easy for a front-end to ensure when the Enum is a direct return
type or member of a stub return type, there are other cases where the object factory can end up
building a nondet Enum, such as generic type substitution and usage-inferred stub return types.
Until (if ever) ci-lazy-methods can precisely mimic the object factory's behaviour, we're better
off tolerating the case where the VALUES array remains missing than killing the entire run.

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: 05fd4ef).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/102518462

Copy link
Contributor

@antlechner antlechner left a comment

Choose a reason for hiding this comment

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

Happy with the invariant going away. But maybe we should print some kind of warning when gen_nondet_enum_init returns false, as this case usually shouldn't happen.

@@ -1460,18 +1460,23 @@ void java_object_factoryt::gen_nondet_array_init(
/// expr = $VALUES[i];
/// where $VALUES is a variable generated by the Java compiler that stores
/// the array that is returned by Enum.values().
void java_object_factoryt::gen_nondet_enum_init(
/// This may fail if the $VALUES static field is not present, which gives the
/// possible values of a particular enum subtype. Ensuring that field is in the
Copy link
Contributor

Choose a reason for hiding this comment

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

⛏️ "which gives the..." <- a bit confusing to have the explanation of what $VALUES is split like that, maybe add this part to the previous sentence?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed this and added a warning message

@smowton smowton force-pushed the smowton/fix/missing-enum-non-fatal branch from 81408c5 to 26fa790 Compare March 14, 2019 18:01
@tautschnig
Copy link
Collaborator

@smowton clang-format and Doxygen are unhappy...

code_blockt &assignments,
const exprt &expr,
const java_class_typet &java_class_type,
const source_locationt &location)
{
const irep_idt &class_name = java_class_type.get_name();
const irep_idt values_name = id2string(class_name) + ".$VALUES";
INVARIANT(
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 An exception might be clearer than a boolean here since it is an error condition, even if we do want to gracefully recover from it.

@thk123
Copy link
Contributor

thk123 commented Mar 15, 2019

Approved prematurely - is there a test case we can add that exhibits this failure at the moment?

@smowton
Copy link
Contributor Author

smowton commented Mar 15, 2019

@thk123 as far as I'm aware, not with JBMC, as the examples I know of require using test-gen's generic type substitution.

@smowton smowton force-pushed the smowton/fix/missing-enum-non-fatal branch from 26fa790 to ff2a673 Compare March 15, 2019 13:31
@thk123
Copy link
Contributor

thk123 commented Mar 15, 2019

@smowton Fair - if you have a test case please send it my way and I'll integrate it into TG

smowton added 3 commits March 15, 2019 14:42
Previously we always expected an Enum type's VALUES array to be present if it may be created in a
stub method. However while this is easy for a front-end to ensure when the Enum is a direct return
type or member of a stub return type, there are other cases where the object factory can end up
building a nondet Enum, such as generic type substitution and usage-inferred stub return types.
Until (if ever) ci-lazy-methods can precisely mimic the object factory's behaviour, we're better
off tolerating the case where the VALUES array remains missing than killing the entire run.
@smowton smowton force-pushed the smowton/fix/missing-enum-non-fatal branch from ff2a673 to 40d72fb Compare March 15, 2019 14:42
@smowton
Copy link
Contributor Author

smowton commented Mar 15, 2019

@thk123 here you go:

public class Test {

    public static void main() {

	MyEnum e = (MyEnum)Stub.get();

    }

}

class Stub {

    public static Object get() { return null; }

}

enum MyEnum { }

@smowton
Copy link
Contributor Author

smowton commented Mar 15, 2019

Of course delete Stub.class before running test-gen, but the result is the stub-type-inference pass makes the stub try to produce a MyEnum, but ci-lazy-loading doesn't know it's going to do that and doesn't force-load the VALUES array it needs to do its job.

@smowton smowton merged commit 0db1830 into diffblue:develop Mar 15, 2019
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.

7 participants