-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Fix #11353 FP uninitvar for struct member set via pointer #5314
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3295,6 +3295,12 @@ struct MemberExpressionAnalyzer : SubExpressionAnalyzer { | |
| : SubExpressionAnalyzer(e, std::move(val), t, s), varname(std::move(varname)) | ||
| {} | ||
|
|
||
| bool match(const Token* tok) const override | ||
| { | ||
| return SubExpressionAnalyzer::match(tok) || | ||
| (Token::simpleMatch(tok->astParent(), ".") && SubExpressionAnalyzer::match(tok->astParent())); | ||
| } | ||
|
|
||
| bool submatch(const Token* tok, bool exact) const override | ||
| { | ||
| if (!Token::Match(tok, ". %var%")) | ||
|
|
@@ -7965,6 +7971,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings) | |
| Token* start = findStartToken(var, tok->next(), &settings->library); | ||
|
|
||
| std::map<Token*, ValueFlow::Value> partialReads; | ||
| Analyzer::Result result; | ||
| if (const Scope* scope = var->typeScope()) { | ||
| if (Token::findsimplematch(scope->bodyStart, "union", scope->bodyEnd)) | ||
| continue; | ||
|
|
@@ -7979,7 +7986,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings) | |
| continue; | ||
| } | ||
| MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings); | ||
| valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings); | ||
| result = valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings); | ||
|
|
||
| for (auto&& p : *analyzer.partialReads) { | ||
| Token* tok2 = p.first; | ||
|
|
@@ -8009,7 +8016,8 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings) | |
| if (partial) | ||
| continue; | ||
|
|
||
| valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings); | ||
| if (result.terminate != Analyzer::Terminate::Modified) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems strange. Why are we skipping forwarding only when the last variable in the list terminates as modified?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This happens for every variable, right?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There is a forward for every variable in the struct.
But this starts at the same spot, so why does the last
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thinking was, because it doesn't do the special MemberExpressionAnalyzer stuff?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea thats it. And the special matching stuff is too just match the lifetimes since we point to class variables. Ideally, we should update the lifetime to point to the correct token, but this would require changing a lot of assumptions through out.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed this in #5320. |
||
| valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings); | ||
| } | ||
| } | ||
|
|
||
|
|
||
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 are we matching the token when the parent matches? That seems wrong.
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.
Otherwise
x(ins.x,lifeTok) ands(expr) don't match.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 see, we probably need to create a different
matchfunction for this purpose as there are other uses like this that will suffer the same issue.