Fixed #8999 (False positive uninitvar related to casting)
This commit is contained in:
parent
fe402498e1
commit
80143725dd
|
@ -925,20 +925,24 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, Alloc al
|
||||||
// Accessing Rvalue member using "." or "->"
|
// Accessing Rvalue member using "." or "->"
|
||||||
if (Token::Match(vartok->previous(), "!!& %var% .")) {
|
if (Token::Match(vartok->previous(), "!!& %var% .")) {
|
||||||
// Is struct member passed to function?
|
// Is struct member passed to function?
|
||||||
if (!pointer && Token::Match(vartok->previous(), "[,(] %name% . %name%")) {
|
if (!pointer) {
|
||||||
// TODO: there are FN currently:
|
// TODO: there are FN currently:
|
||||||
// - should only return false if struct member is (or might be) array.
|
// - should only return false if struct member is (or might be) array.
|
||||||
// - should only return false if function argument is (or might be) non-const pointer or reference
|
// - should only return false if function argument is (or might be) non-const pointer or reference
|
||||||
const Token *tok2 = vartok->next();
|
bool unknown = false;
|
||||||
do {
|
const Token *possibleParent = getAstParentSkipPossibleCastAndAddressOf(vartok, &unknown);
|
||||||
tok2 = tok2->tokAt(2);
|
if (Token::Match(possibleParent, "[(,]")) {
|
||||||
} while (Token::Match(tok2, ". %name%"));
|
if (unknown)
|
||||||
if (Token::Match(tok2, "[,)]"))
|
return false; // TODO: output some info message?
|
||||||
return false;
|
const int use = isFunctionParUsage(vartok, pointer, alloc);
|
||||||
} else if (pointer && alloc != CTOR_CALL && Token::Match(vartok, "%name% . %name% (")) {
|
if (use >= 0)
|
||||||
return true;
|
return (use>0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pointer && alloc != CTOR_CALL && Token::Match(vartok, "%name% . %name% ("))
|
||||||
|
return true;
|
||||||
|
|
||||||
bool assignment = false;
|
bool assignment = false;
|
||||||
const Token* parent = vartok->astParent();
|
const Token* parent = vartok->astParent();
|
||||||
while (parent) {
|
while (parent) {
|
||||||
|
|
|
@ -3053,7 +3053,8 @@ private:
|
||||||
" struct AB ab;\n"
|
" struct AB ab;\n"
|
||||||
" do_something(ab.a);\n"
|
" do_something(ab.a);\n"
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
|
ASSERT_EQUALS("[test.c:5]: (error) Uninitialized variable: ab\n"
|
||||||
|
"[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("struct AB { int a; int b; };\n"
|
checkUninitVar("struct AB { int a; int b; };\n"
|
||||||
"void do_something(const struct AB &ab) { a = ab.a; }\n"
|
"void do_something(const struct AB &ab) { a = ab.a; }\n"
|
||||||
|
@ -3183,12 +3184,19 @@ private:
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar("struct AB { unsigned char a[10]; };\n" // #8999 - cast
|
||||||
|
"void f(void) {\n"
|
||||||
|
" struct AB ab;\n"
|
||||||
|
" strcpy((char *)ab.a, STR);\n"
|
||||||
|
"}\n", "test.c");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("struct AB { char a[10]; };\n"
|
checkUninitVar("struct AB { char a[10]; };\n"
|
||||||
"void f(void) {\n"
|
"void f(void) {\n"
|
||||||
" struct AB ab;\n"
|
" struct AB ab;\n"
|
||||||
" strcpy(x, ab.a);\n"
|
" strcpy(x, ab.a);\n"
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
TODO_ASSERT_EQUALS("error", "", errout.str());
|
ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ab\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("struct AB { int a; };\n"
|
checkUninitVar("struct AB { int a; };\n"
|
||||||
"void f(void) {\n"
|
"void f(void) {\n"
|
||||||
|
|
Loading…
Reference in New Issue