Fixed #6246 (Defect: False positive due to ignoring struct initialisation when nested in a loop and assigned to a member)

This commit is contained in:
Daniel Marjamäki 2017-06-30 13:41:19 +02:00
parent 3ab8466415
commit 22919da9a8
2 changed files with 22 additions and 4 deletions

View File

@ -778,10 +778,24 @@ bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const
if (isMemberVariableAssignment(tok, membervar)) { if (isMemberVariableAssignment(tok, membervar)) {
bool assign = true; bool assign = true;
bool rhs = false; bool rhs = false;
// Used for tracking if an ")" is inner or outer
const Token *rpar = nullptr;
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
if (tok2->str() == "=") if (tok2->str() == "=")
rhs = true; rhs = true;
if (tok2->str() == ";")
// Look at inner expressions but not outer expressions
if (!rpar && tok2->str() == "(")
rpar = tok2->link();
else if (tok2->str() == ")") {
// No rpar => this is an outer right parenthesis
if (!rpar)
break;
if (rpar == tok2)
rpar = nullptr;
}
if (tok2->str() == ";" || (!rpar && tok2->str() == ","))
break; break;
if (rhs && tok2->varId() == var.declarationId() && isMemberVariableUsage(tok2, var.isPointer(), alloc, membervar)) { if (rhs && tok2->varId() == var.declarationId() && isMemberVariableUsage(tok2, var.isPointer(), alloc, membervar)) {
assign = false; assign = false;
@ -792,9 +806,6 @@ bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const
return true; return true;
} }
if (Token::Match(tok, "%name% ="))
return true;
if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar)) if (isMemberVariableUsage(tok, var.isPointer(), alloc, membervar))
usetok = tok; usetok = tok;
else if (Token::Match(tok->previous(), "[(,] %name% [,)]")) else if (Token::Match(tok->previous(), "[(,] %name% [,)]"))

View File

@ -3346,6 +3346,13 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
checkUninitVar("struct AB { int a; };\n"
"void f() {\n"
" struct AB ab;\n"
" while (x) { init(&ab); z = ab.a; }\n"
"}");
ASSERT_EQUALS("", errout.str());
// address of member // address of member
checkUninitVar("struct AB { int a[10]; int b; };\n" checkUninitVar("struct AB { int a[10]; int b; };\n"
"void f() {\n" "void f() {\n"