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++: Fix spurious reference flow #11254
base: mathiasvp/replace-ast-with-ir-use-usedataflow
Are you sure you want to change the base?
C++: Fix spurious reference flow #11254
Conversation
| exists(IRBlock bb2, int i2, Definition def | | ||
| adjacentDefRead(pragma[only_bind_into](def), pragma[only_bind_into](bb1), | ||
| pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and | ||
| def.getSourceVariable() = v and |
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.
Why wasn't this here before?
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.
I thought it wasn't needed because of the conditions on the def/use and the use (i.e., they are both attached to the same variable). This was actually pointed out by Tom in the initial PR here, but I managed to convince him that this was okay
|
This PR is ready for reviewing. I was hoping to split up this work into three PRs, but they all annoyingly depend on each other "PR one": Disable reference/value conflation in dataflowThis is done in 7408931. This is necessary for 235a069, but introduces missing/spurious flow that will be fixed in 3b1b8cc. 2cebd5c accepts the changes (where the missing/spurious flow is shown). "PR two": Make
|
| // The IR results for this test _is_ equivalent to the AST ones. | ||
| // The IR annotation is just "ir" because the sink of the unitialized source at | ||
| // 428:7 is value of `local`, but the sink of the source from `intPointerSource` | ||
| // value of `*local` (i.e., the indirection node of `local`). So unlike AST dataflow, | ||
| // each of these two sinks correspond to a unique source, and thus we don't need to | ||
| // attach a location annotation to it. |
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.
Should we still provide the location annotations to guarantee that if these get conflated we'll have a test failure?
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.
I think that's a good idea. I think this requires adding another tag though, right (since I don't think we can have tags with optional values)?
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.
I would prefer to add this in another PR if that's okay with you, though (since this PR is already three PRs
|
I just force-pushed away a commit I added by mistake. Sorry about that! |
| exists(int indirectionIndex | result = this.asParameter(indirectionIndex) | | ||
| if result.getUnspecifiedType() instanceof ReferenceType | ||
| then indirectionIndex = 1 | ||
| else indirectionIndex = 0 | ||
| ) |
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.
I think we can now remove similar code from the dataflow tests where we added it earlier.
On the use-use-flow feature-branch we were getting spurious flow like:
when the
sourcedataflow node was defined assource.asParameter().hasName("source"). This turns out to be becausesource.asParameter()defaults tosource.asParameter(0), which means that the value ofsourcewas marked as the source instead of the value of*source(if we pretend that the source is of a pointer type instead of a reference type).Ideally, the fix in 5e9e7da should be enough to fix this. However, the first commit is a necessary precondition for this. This first commit fixes two things:
adjacentDefRead: Previously, when we were flowing from one def/use to an adjacent use we did the following:which amounts to saying:
vis at position(bb1, i1)(bb1, i1)and(bb2, i2)vis at position(bb2, i2).However, note that point 2 doesn't talk about which variable is participating in the adjacent-def/use-use relationship. So in our example above, we'd have a use-use relation between
source(note: not*source) insource = 0andsourceinsink(source). And sincesourceand*sourceare located at the same index in the same block we'd get use-use flow between*sourceinsource = 0and*sourceinsink(source).The fix is very simple: instead of ignoring the first column of
adjacentDefReadwe simply check that the variable in question is actuallyv.