-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Ruby: Case barrier guards #10981
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
Closed
Closed
Ruby: Case barrier guards #10981
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Contributor
hmac
commented
Oct 26, 2022
- Ruby: Add basic case string comp barrier guard
- Ruby: Use better names in barrier guard predicates
- Ruby: Add more case barrier guard tests
- Ruby: Add SplatExprCfgNode
- Ruby: Recognise more case barrier guards
- Ruby: Fix barrier guard type
- Ruby: Add placeholder test
- Ruby: Add case barrier to command injection query
- Ruby: Merge case barrier with string const barrier
- Ruby: Add custom barrier guard for cases
- Ruby: Move when clause special-case to shared code
This recognises barriers of the form
case foo
when "some string literal"
foo
end
where the read of `foo` inside the `when` is guarded by the comparison
of `foo` with `"some string literal"`.
We don't yet recognise more complex constructs such as case array
inclusion.
A previous changed relaxed the signature from ExprCfgNode to AstCfgNode.
Both these barriers are for comparison with a constant string, so it seems cleaner to merge them together.
`when` clauses in case expressions exert control over their
corresponding `then` branches, but this is not easily noticeable in the
CFG. The individual patterns in the clause have conditional successors,
not the `when` node itself.
Specifically, this means that in an expression such as
case foo
when "foo", "bar"
foo
end
the pattern `"bar"` technically does not control the read of `foo` on
line 3, because that read is also reachable from the previous pattern
`"foo"`.
Instead of considering the patterns in isolation, we instead consider
the entire `when` clause, provided that all patterns have edges to the
`then` node with the same successor.
In practice this means we copy the implementation of
`DataFlow::BarrierGuard` but use a custom predicate in place of
`ConditionBlock.controls`.
This means that we will always treat `when` clauses specially when considering whether one basic block controls another. Provided the special case is correect, I think this is fine to do. It allows us to simplify the case barrier guard by using the parameterized module.
fefa973 to
b2b4842
Compare
Contributor
Author
|
Closing in favour of #11114 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.