- Notifications
You must be signed in to change notification settings - Fork1.7k
C++: Fix global variable dataflow FP#20040
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Conversation
…' in the 'IRfunction' for 'v' itself.
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.
Pull Request Overview
This PR fixes a false positive in global variable dataflow analysis for C++ code. The issue occurs in an edge case where a global variable is used within its own initialization expression, causing incorrect dataflow through SSA definitions.
- Adds a test case demonstrating the problematic scenario with self-referential global variable initialization
- Modifies the SSA internals to exclude
InitialGlobalValue
nodes fromIRFunction
s that initialize the same global variable - Updates expected test results to reflect the new test case
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
File | Description |
---|---|
test.cpp | Adds test case for self-referential global variable initialization |
dataflow-consistency.expected | Updates expected test results for the new test case |
SsaInternals.qll | Implements fix by filtering out problematic SSA definitions |
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 is happy.
2ed54d5
intogithub:mainUh oh!
There was an error while loading.Please reload this page.
This PR fixes a very odd corner case of global dataflow through global variables.
Consider this snippet (which I've also added as a test):
int recursion = (sink(recursion), source());
The IR we generate for this snippet is roughly equivalent to:
where
__recursion
represents the actual global variable. Since this is anIRFunction
just like any otherFunction
, it gets an initial SSA definition of the global variables that it reads, and it gets a final SSA use of the global variables that it defines. So for the point-of-view of dataflow the function ends up looking like:where
__initialize_global
represents the initial SSA definition (aInitialGlobalValue
node), and__final_use(recursion)
represents the final SSA use (aFinalGlobalValue
node).And now global variable dataflow does its things and this happens:
recursion
at// (1)
flows to the final SSA use at// (2)
// (2)
to the global dataflow node (aGlobalLikeVariableNode
) forrecursion
recursion
to the initial SSA definition forrecursion
at// (3)
// (3)
to the use at// (4)
.But clearly we should not have flow in this case! So this PR fixes the FP by removing the
InitialGlobalValue
node for some global variablev
at the entry for theIRFunction
that initializesv
.I don't think this will ever happen on any real codebase. But since it was so easy to fix we might as well get this fix in 😄