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

Support refinement for conditions of comparisons #389

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

d367wang
Copy link

@d367wang d367wang commented Feb 20, 2022

A split of #331

Co-authored-by: Jenny Xiang j.tt.xiang@gmail.com

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 @d367wang !

src/checkers/inference/dataflow/InferenceTransfer.java Outdated Show resolved Hide resolved
return;
}
Tree tree = var.getTree();
ConstraintManager constraintManager = InferenceMain.getInstance().getConstraintManager();
Copy link
Member

Choose a reason for hiding this comment

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

I think these are the first constraints that are created by InferenceTransfer - so far, this only created Slots.
Why is this needed for these constraints? Can you add a comment to the method explaining this? The method name should also reflect this.

Copy link
Author

Choose a reason for hiding this comment

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

I think it works in either ways. I guess putting constraint creation here is just for convenience. I can move it to InferenceVisitor.visitBinary for consistency. In that case, we should (1) check if it's a comparison (2) retrieve the comparison slots associated from the cache.

Copy link
Member

Choose a reason for hiding this comment

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

Did you get a chance to try whether this is nicer in InferenceVisitor? For refinement variables we seem to add the subtype constraints in InferenceVisitor. So maybe something similar would work for these ComparisonSlots.

Copy link
Author

@d367wang d367wang Mar 20, 2022

Choose a reason for hiding this comment

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

Not all the constraints are created in xxxVisitor. E.g., the equality constraint associated with an assignment is created in the transfer function, as

InferenceMain.getInstance().getConstraintManager().addEqualityConstraint(refinementVariableSlot, valueSlot);

For refinement variables we add the subtype constraints in InferenceVisitor may be because we want to reuse the super method BaseTypeVisitor.visitAssignment, which checks if RHS <: LHS.

So it makes sense to put the type rule-based constraints in xxxVisitory, and add inherent constraints of a slot in xxxTransfer when the slot is created.

Copy link
Author

Choose a reason for hiding this comment

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

Besides, regarding the comparison variable slot, I think the subtype constraints (compareSlot <: declareType) are not precise. It's more precise to create compareSlot <: typeBeforeComparison, i.e. line 443-446 can be removed.

src/checkers/inference/dataflow/InferenceTransfer.java Outdated Show resolved Hide resolved
@@ -31,7 +31,7 @@
private AnnotationLocation location;

/** Refinement variables that refine this slot. */
Copy link
Member

Choose a reason for hiding this comment

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

What is the motivation for this change? Can you update the javadoc to explain what kinds of VariableSlots to expect?

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 name of the method and field be updated to reflect this change?

Copy link
Author

Choose a reason for hiding this comment

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

The comment for this field has been updated.

I think the current name refinedToSlots makes sense, considering that both RefinementVariableSlot and ComparisonVariableSlot can refine a `VariableSlot.

ConstraintManager constraintManager = InferenceMain.getInstance().getConstraintManager();
SlotManager slotManager = getInferenceAnalysis().getSlotManager();

AnnotatedTypeMirror atm = typeFactory.getAnnotatedType(tree);
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this use getAnnotatedTypeLhs?

Copy link
Author

@d367wang d367wang Mar 7, 2022

Choose a reason for hiding this comment

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

We have a problem in getting the declared type using getAnnotatedTypeLhs in CFI, because of the mutable ATM in the elementToAtm cache (I have an open PR #362 intended to fix it by duplicating the ATM before writing or after reading).

The effect is, getAnnotatedTypeLhs give us the refined type right after initialization, no matter how many times the variable is reassigned.

A common workaround for this issue in CFI is to use getAnnotatedType (which is usually a RefinementVariableSlot), and then get the declared type of the RefinementVariableSlot, like Lines 436-439 in this file, and

if (slotToRefine instanceof RefinementVariableSlot) {

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation! Let's try to clean this up with or after #362!

@d367wang d367wang assigned wmdietl and unassigned d367wang Mar 7, 2022
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! A few small comments/questions.

return;
}
Tree tree = var.getTree();
ConstraintManager constraintManager = InferenceMain.getInstance().getConstraintManager();
Copy link
Member

Choose a reason for hiding this comment

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

Did you get a chance to try whether this is nicer in InferenceVisitor? For refinement variables we seem to add the subtype constraints in InferenceVisitor. So maybe something similar would work for these ComparisonSlots.

ConstraintManager constraintManager = InferenceMain.getInstance().getConstraintManager();
SlotManager slotManager = getInferenceAnalysis().getSlotManager();

AnnotatedTypeMirror atm = typeFactory.getAnnotatedType(tree);
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation! Let's try to clean this up with or after #362!

}

@Override
public TransferResult<CFValue, CFStore> visitEqualTo(
Copy link
Member

Choose a reason for hiding this comment

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

These only handle equal and not-equal. Shouldn't other comparisons also be handled?

Copy link
Author

Choose a reason for hiding this comment

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

Comparison slots are created only when type refinement can be performed. For non-numeric types (general case in CFI), type refinement is only possible when the comparison is == or !=.

Other kinds of comparisons are only applicable for numeric types and can be defined in specific type system, like value-inference.

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.

2 participants