-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
C++: Extend barrier guards to handle phi inputs #16677
Conversation
…a phi input dataflow node.
b78f471
to
97f0c75
Compare
DCA results:
Going forward, I think we should strive to use more barrier guards instead of adding manual barrier logic. |
int x = source(); | ||
|
||
if(!guarded(x)) { | ||
x = 0; | ||
} | ||
sink(x); // $ SPURIOUS: ast | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How am I supposed to read tests like these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
guarded
is a bad name for the barrier guard in this case. The function should really be read as isSafe
. So this is a standard dataflow test, except that there's a function guarded
(read: isSafe
) to check if the value produced by source()
is allowed to flow to sink
.
So in this case, the value produced by source()
is either safe (i.e., guarded(x)
is true), or the value is reassigned to 0.
And after these changes, IR dataflow realizes that the value of x
is always either 0 or guarded(x)
holds when reaching sink(x)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. That helps!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some simple QL docs comments. Also, does C++ use phi-reads like Ruby? In all cases, perhaps add a test similar to the one from Ruby.
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Outdated
Show resolved
Hide resolved
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Outdated
Show resolved
Hide resolved
We use phi-reads in C++ like in Ruby, yep. I'll add that test right away! |
…y. Rather, it's the GuardCondition library.
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Dismissed
Show resolved
Hide resolved
I've added that test in f7b2d98, and everything now works 🎉 I think the problem with |
exists(SourceVariable sv, IRBlock bb2, int i2 | | ||
adjustForPointerArith(pun, sv, bb2, i2) and | ||
useToNode(bb2, i2, sv, n) | ||
// The reason for this predicate is a bit annoying: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not really a predicate anymore, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I've just removed the line now in 8aaa2a1. I've reached a state of acceptance of this complication 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM if DCA comes back happy.
DCA is mostly unchanged compared to the previous run. We get rid of one more lost result on I don't quite understand why we didn't exclude it before, but it certainly looks like it should be excluded from this change. So I'm happy with this 🎉 Merging! |
This is the C/C++ version of #15985. The strategy is completely identical to the Ruby version: create a new dataflow node branch for phi inputs, and modify dataflow so that we do
def -> phi input -> phi
instead ofdef -> phi
. We then extend the barrier guard implementation so that it can put barriers on these new phi input nodes.I've also done some cleanup along the way.
Commit-by-commit review recommended.