Skip to content
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

Remove non-static fields from the initial store of a static method #216

Merged
merged 13 commits into from
Apr 22, 2022

Conversation

AndrewShf
Copy link
Member

@AndrewShf AndrewShf commented Apr 10, 2022

This PR is to fix issue #215

Below is the CFG graph produced by this branch.
Screen Shot 2022-04-09 at 9 28 16 PM

As we can see, this.f has been removed from the initial store.

@AndrewShf AndrewShf changed the title fix issue 215 in eisop Remove non-static variable from initial store of a static method Apr 10, 2022
@AndrewShf AndrewShf changed the title Remove non-static variable from initial store of a static method Remove non-static field variable from initial store of a static method Apr 10, 2022
@AndrewShf AndrewShf changed the title Remove non-static field variable from initial store of a static method Remove non-static field variable from the initial store of a static method Apr 10, 2022
@AndrewShf AndrewShf requested a review from wmdietl April 10, 2022 13:44
Copy link
Member

@wmdietl wmdietl left a comment

Choose a reason for hiding this comment

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

Thanks, just a small suggestion.

Separately, can you look whether store.insertValue can ever be called twice for the same field, first with the initializer and then with the declared type? The conditions don't seem to exclude this.

Should the first if also include varEle.getEnclosingElement().equals(classEle)? It would be more readable if that condition is extracted into another boolean with a more descriptive name.

@wmdietl wmdietl changed the title Remove non-static field variable from the initial store of a static method Remove non-static fields from the initial store of a static method Apr 10, 2022
@AndrewShf
Copy link
Member Author

Thanks, just a small suggestion.

Separately, can you look whether store.insertValue can ever be called twice for the same field, first with the initializer and then with the declared type? The conditions don't seem to exclude this.

Should the first if also include varEle.getEnclosingElement().equals(classEle)? It would be more readable if that condition is extracted into another boolean with a more descriptive name.

For the first one, yes, the store.insertValue could be inserted twice. For example a field final String str = "hello"
(So, I guess I need to move my code before the first insertion)

For the second question, yes, I think so. But in what circumstance will the classEle not equal to varEle.getEnclosingElement()?

@wmdietl
Copy link
Member

wmdietl commented Apr 11, 2022

Re 1: Can you test what happens? I would assume the second insert overwrites the value from the first, making this rather pointless.

Re 2: Remove the check and see whether a test case fails. It might be related to nested classes and that the returned set of fields also contains fields from nested or enclosing classes that shouldn't be there. (Although, why shouldn't the store contain a field from an enclosing class? So maybe just nested classes should be excluded.)

@AndrewShf
Copy link
Member Author

AndrewShf commented Apr 11, 2022

Re 1: Can you test what happens? I would assume the second insert overwrites the value from the first, making this rather pointless.

Re 2: Remove the check and see whether a test case fails. It might be related to nested classes and that the returned set of fields also contains fields from nested or enclosing classes that shouldn't be there. (Although, why shouldn't the store contain a field from an enclosing class? So maybe just nested classes should be excluded.)

Now I understand! the second insert with value declared is the Lhs and the first insert with value initializer is the Rhs. So if the second insert is triggered, then the second insert would be overwritten.
There's one scenario though: only the first insert is triggered, the second one in if and else branches are not triggered. That may due to this is a nested class (varEle.getEnclosingElement().equals(classEle)). Or the isNotFullyInitializedReceiver returns true in the if branch.

@AndrewShf
Copy link
Member Author

After removing varEle.getEnclosingElement().equals(classEle), two nullness checks fail, one is issue354.java, another is issue904.java.
typetools#904
typetools#354

Is this because, this version inserts the field from enclosing class in store as initialized? (suppose to be under initialization)

Copy link
Member

@wmdietl wmdietl left a comment

Choose a reason for hiding this comment

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

Thanks!

TypeElement classEle = TreeUtils.elementFromDeclaration(classTree);
for (FieldInitialValue<V> fieldInitialValue : analysis.getFieldInitialValues()) {
VariableElement varEle = fieldInitialValue.fieldDecl.getField();
boolean fieldNotFromEnclosingClass = varEle.getEnclosingElement().equals(classEle);
Copy link
Member

Choose a reason for hiding this comment

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

Should the Not be removed from the variable name?

Copy link
Member Author

Choose a reason for hiding this comment

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

If varEle.getEnclosingElement().equals(classEle) is true, varEle is in classEle, then this field is not from enclosing class right?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure where the confusion is here. The enclosing element of varEle is some class. If that class is equal to classEle, then the field is directly within classEle.
What element do you mean with "the enclosing class"?

Copy link
Member Author

@AndrewShf AndrewShf Apr 20, 2022

Choose a reason for hiding this comment

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

Meaning classEle is the nested class. The "enclosing class", encloses classEle. So if the field is directly within classEle, it's not from the enclosing class.
Yeah, the naming is a bit ambiguous. How about fieldNotFromOuterClass ?

Copy link
Member

Choose a reason for hiding this comment

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

It's usually easier to avoid negations. How about isFieldOfCurrentClass?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I agree!

TypeElement classEle = TreeUtils.elementFromDeclaration(classTree);
for (FieldInitialValue<V> fieldInitialValue : analysis.getFieldInitialValues()) {
VariableElement varEle = fieldInitialValue.fieldDecl.getField();
boolean fieldNotFromEnclosingClass = varEle.getEnclosingElement().equals(classEle);
Copy link
Member

Choose a reason for hiding this comment

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

It's usually easier to avoid negations. How about isFieldOfCurrentClass?

AndrewShf and others added 3 commits April 20, 2022 20:44
Co-authored-by: Werner Dietl <wdietl@gmail.com>
@AndrewShf
Copy link
Member Author

I think this pull request is nearly done. During the discussion, we found one false negative, and I opened a new issue for this.
#226

Copy link
Member

@wmdietl wmdietl left a comment

Choose a reason for hiding this comment

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

Thanks for the improvements and cleanups!

@wmdietl wmdietl merged commit 92d53e8 into eisop:master Apr 22, 2022
@AndrewShf AndrewShf deleted the fix_initial_store branch September 17, 2022 23:29
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