Uninitialized struct members: Improved checking when struct member is used in expression

This commit is contained in:
Daniel Marjamki 2013-01-19 10:09:58 +01:00
parent 8647e4c0d0
commit 3cf0e88fbe
2 changed files with 40 additions and 3 deletions

View File

@ -1321,7 +1321,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
while (tok && tok->str() != ";") { while (tok && tok->str() != ";") {
// variable is seen.. // variable is seen..
if (tok->varId() == var.varId()) { if (tok->varId() == var.varId() && (membervar == NULL)) {
// Use variable // Use variable
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer())) if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
uninitvarError(tok, tok->str()); uninitvarError(tok, tok->str());
@ -1343,8 +1343,14 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
// variable is seen.. // variable is seen..
if (tok->varId() == var.varId()) { if (tok->varId() == var.varId()) {
if (membervar) { if (membervar) {
if (Token::Match(tok, "%var% . %var% [=.[]") && tok->strAt(2) == membervar->name()) if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar->name()) {
if (Token::Match(tok->tokAt(3), "[=.[]"))
return true; return true;
else if (Token::Match(tok->previous(), "%op%") || Token::Match(tok->previous(), "[|="))
uninitStructMemberError(tok, tok->str() + "." + membervar->name());
else
return true;
}
else if (tok->strAt(1) == "=") else if (tok->strAt(1) == "=")
return true; return true;
else if (tok->strAt(-1) == "&") else if (tok->strAt(-1) == "&")

View File

@ -2564,6 +2564,20 @@ private:
"}\n", "test.c", true); "}\n", "test.c", true);
ASSERT_EQUALS("[test.c:6]: (error) Uninitialized struct member: ab.b\n", errout.str()); ASSERT_EQUALS("[test.c:6]: (error) Uninitialized struct member: ab.b\n", errout.str());
checkUninitVar2("struct AB { int a; int b; };\n"
"void f(void) {\n"
" struct AB ab;\n"
" int a = ab.a;\n"
"}\n", "test.c", true);
ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
checkUninitVar2("struct AB { int a; int b; };\n"
"void f(void) {\n"
" struct AB ab;\n"
" buf[ab.a] = 0;\n"
"}\n", "test.c", true);
ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
checkUninitVar2("struct AB { int a; int b; };\n" checkUninitVar2("struct AB { int a; int b; };\n"
"void do_something(const struct AB ab);\n" "void do_something(const struct AB ab);\n"
"void f(void) {\n" "void f(void) {\n"
@ -2607,6 +2621,23 @@ private:
"}\n", "test.c", true); "}\n", "test.c", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// return
checkUninitVar2("struct AB { int a; int b; };\n"
"void f(void) {\n"
" struct AB ab;\n"
" ab.a = 0;\n"
" return ab.b;\n"
"}\n", "test.c", true);
TODO_ASSERT_EQUALS("error", "", errout.str());
checkUninitVar2("struct AB { int a; int b; };\n"
"void f(void) {\n"
" struct AB ab;\n"
" ab.a = 0;\n"
" return ab.a;\n"
"}\n", "test.c", true);
ASSERT_EQUALS("", errout.str());
// checkIfForWhileHead // checkIfForWhileHead
checkUninitVar2("struct FRED {\n" checkUninitVar2("struct FRED {\n"
" int a;\n" " int a;\n"