Fix #12612 FP uninitvar with pointer alias in subfunction#7249
Fix #12612 FP uninitvar with pointer alias in subfunction#7249chrchr-github wants to merge 4 commits intocppcheck-opensource:mainfrom
Conversation
| return values.count(tok->varId()) > 0 || | ||
| std::any_of(values.begin(), values.end(), [&](const std::pair<nonneg int, ValueFlow::Value>& p) { | ||
| return p.second.isUninitValue() && p.second.tokvalue->varId() == tok->varId(); | ||
| }); |
There was a problem hiding this comment.
Why is this extra check needed?
There was a problem hiding this comment.
Which check exactly? We now match in case there is an alias that has an uninit value pointing to the variable in question. But I'm not sure if it is correct to only check for uninit values.
There was a problem hiding this comment.
That should happen in the analyzeToken function, not here. We are already checking for aliases there as well.
Finally the tokvalue is not always an alias either.
There was a problem hiding this comment.
analyzeToken() has this:
Action la = analyzeLifetime(lifeTok);
if (la.matches()) { ...So matches() needs to return true for the propagation of the uninit value to stop.
I looked at how that works for local code and tried to make the same stuff happen with a subfunction/valueFlowInjectParameter()
There was a problem hiding this comment.
So matches() needs to return true for the propagation of the uninit value to stop.
Its not that matches() needs to return true, but that analyzeLifetime should return Action::Match, but I also think it can return Action::Read as well as the isAliasModified will handle it for cases where its not an exact match.
So it seems like you are modifying match so analyzeLifetime returns Action::Match, which is not the right approach. The match function is for exact matches, not to match aliases. That can lead to FPs. This needs to be done in either analyzeToken or analyzeLifetime where we are already checking for aliases.
| const Token* lifeTok = nullptr; | ||
| for (const ValueFlow::Value& v:ref->astOperand1()->values()) { | ||
| if (!v.isLocalLifetimeValue()) | ||
| if (!v.isLocalLifetimeValue() && !v.isSubFunctionLifetimeValue()) |
There was a problem hiding this comment.
Instead of skipping subfunction lifetimes, you could just check that the path is the same if the propagated value's path(ie the value returned from getValue(lifetok)) is not zero.
There was a problem hiding this comment.
Subfunction lifetimes were skipped before this change, and we didn't proceed to analyzeLifetime() below.
There was a problem hiding this comment.
I see, I read it backwards. Its enabling it. We still need to check the correct path to avoid FPs.
|
|
|
@pfultz2 since you reviewed before .. I would really appreciate your eyes on this again.. |
|
I think test-my-pr.py would be good to run. However it currently does not work very well. I believe after I merge #8491 it will work better.. |
|
I asked Claude to review this. Feel free to ignore comments.. but here is what Claude had to say: Hunk 2 — vf_analyzers.cpp:1074 (MultiValueFlowAnalyzer::match)Change: Extend match() to also return true when any tracked value is UNINIT and its tokvalue->varId() equals the queried token's varId. Concerns:
Test coverageOne test case is added, which covers the minimal reproduction. Suggested additions:
|



No description provided.