diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index c17bf3201..6f0b517ed 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -925,20 +925,24 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, Alloc al // Accessing Rvalue member using "." or "->" if (Token::Match(vartok->previous(), "!!& %var% .")) { // Is struct member passed to function? - if (!pointer && Token::Match(vartok->previous(), "[,(] %name% . %name%")) { + if (!pointer) { // TODO: there are FN currently: // - 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 - const Token *tok2 = vartok->next(); - do { - tok2 = tok2->tokAt(2); - } while (Token::Match(tok2, ". %name%")); - if (Token::Match(tok2, "[,)]")) - return false; - } else if (pointer && alloc != CTOR_CALL && Token::Match(vartok, "%name% . %name% (")) { - return true; + bool unknown = false; + const Token *possibleParent = getAstParentSkipPossibleCastAndAddressOf(vartok, &unknown); + if (Token::Match(possibleParent, "[(,]")) { + if (unknown) + return false; // TODO: output some info message? + const int use = isFunctionParUsage(vartok, pointer, alloc); + if (use >= 0) + return (use>0); + } } + if (pointer && alloc != CTOR_CALL && Token::Match(vartok, "%name% . %name% (")) + return true; + bool assignment = false; const Token* parent = vartok->astParent(); while (parent) { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index a24bad238..1e7d11239 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -3053,7 +3053,8 @@ private: " struct AB ab;\n" " do_something(ab.a);\n" "}\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" "void do_something(const struct AB &ab) { a = ab.a; }\n" @@ -3183,12 +3184,19 @@ private: "}\n", "test.c"); 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" "void f(void) {\n" " struct AB ab;\n" " strcpy(x, ab.a);\n" "}\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" "void f(void) {\n"