Uninitialized variables: Improved handling of function calls when struct members are checked

This commit is contained in:
Daniel Marjamäki 2014-03-20 06:48:17 +01:00
parent e48dfb0e6a
commit 8de4246713
2 changed files with 36 additions and 1 deletions

View File

@ -1841,8 +1841,34 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str
return true; 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) == "&") {
if (Token::Match(tok->tokAt(-2), "[(,] & %var%")) {
// locate start parentheses in function call..
unsigned int argumentNumber = 0;
const Token *ftok = tok;
while (ftok && !Token::Match(ftok, "[;{}(]")) {
if (ftok->str() == ")")
ftok = ftok->link();
else if (ftok->str() == ",")
++argumentNumber;
ftok = ftok->previous();
}
// is this a function call?
ftok = ftok ? ftok->previous() : NULL;
if (Token::Match(ftok, "%var% (")) {
// check how function handle uninitialized data arguments..
const Function *function = ftok->function();
const Variable *arg = function ? function->getArgumentVar(argumentNumber) : NULL;
const Token *argStart = arg ? arg->typeStartToken() : NULL;
while (argStart && argStart->previous() && argStart->previous()->isName())
argStart = argStart->previous();
if (Token::Match(argStart, "const struct| %type% * const| %var% [,)]"))
return false;
}
}
return true; return true;
}
return false; return false;
} }

View File

@ -3000,6 +3000,15 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar2("struct ABC { int a; int b; int c; };\n"
"void foo(int x, const struct ABC *abc);\n"
"void bar(void) {\n"
" struct ABC abc;\n"
" foo(123, &abc);\n"
" return abc.b;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized struct member: abc.b\n", errout.str());
// return // return
checkUninitVar2("struct AB { int a; int b; };\n" checkUninitVar2("struct AB { int a; int b; };\n"
"void f(void) {\n" "void f(void) {\n"