diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 9ef52b334..05c7cc79f 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -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; } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 032d86f98..bdcaed7cd 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -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"