Fix uninitvar false positive in designed initializers (#5079)
Stop interpreting struct fields in designed initializers as usage of local variables which can happen if they share the same name. ``` $ cat test.c struct a { int b; }; int main() { char *b; extern int foo(struct a *); return foo(&(struct a){.b = 0}); } $ cppcheck --quiet test.c test.c:5:27: error: Uninitialized variable: b [legacyUninitvar] return foo(&(struct a){.b = 0}); ```
This commit is contained in:
parent
fb850a844b
commit
3d6c453058
|
@ -1123,6 +1123,10 @@ const Token* CheckUninitVar::isVariableUsage(bool cpp, const Token *vartok, cons
|
|||
// (type &)x
|
||||
else if (valueExpr->astParent()->isCast() && valueExpr->astParent()->isUnaryOp("(") && Token::simpleMatch(valueExpr->astParent()->link()->previous(), "& )"))
|
||||
valueExpr = valueExpr->astParent();
|
||||
// designated initializers: {.x | { ... , .x
|
||||
else if (Token::simpleMatch(valueExpr->astParent(), ".") &&
|
||||
Token::Match(valueExpr->astParent()->previous(), ",|{"))
|
||||
valueExpr = valueExpr->astParent();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ private:
|
|||
TEST_CASE(uninitvar_ipa);
|
||||
TEST_CASE(uninitvar_memberfunction);
|
||||
TEST_CASE(uninitvar_nonmember); // crash in ycmd test
|
||||
TEST_CASE(uninitvarDesignatedInitializers);
|
||||
|
||||
TEST_CASE(isVariableUsageDeref); // *p
|
||||
TEST_CASE(isVariableUsageDerefValueflow); // *p
|
||||
|
@ -6955,6 +6956,24 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: foo\n", errout.str());
|
||||
}
|
||||
|
||||
void uninitvarDesignatedInitializers() {
|
||||
checkUninitVar("struct a { int b; };\n"
|
||||
"int main() {\n"
|
||||
" char *b;\n"
|
||||
" extern int f(struct a *);\n"
|
||||
" return f(&(struct a){.b = 0});\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar("struct a { int b, c; };\n"
|
||||
"int main() {\n"
|
||||
" char *c;\n"
|
||||
" extern int f(struct a *);\n"
|
||||
" return f(&(struct a){.b = 0, .c = 0});\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void isVariableUsageDeref() {
|
||||
// *p
|
||||
checkUninitVar("void f() {\n"
|
||||
|
|
Loading…
Reference in New Issue