diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index d0bf9661b..c6645bf5a 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -196,6 +196,8 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set void CheckUninitVar::checkStruct(const Token *tok, const Variable &structvar) { const Token *typeToken = structvar.typeStartToken(); + while (Token::Match(typeToken, "%name% ::")) + typeToken = typeToken->tokAt(2); const SymbolDatabase * symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope *scope2 : symbolDatabase->classAndStructScopes) { if (scope2->className == typeToken->str() && scope2->numConstructors == 0U) { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 735efe7a7..8e0d12066 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6052,6 +6052,55 @@ private: " if ((&a)->bar) ;\n" "}"); ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("struct A {\n" // #10200 + " struct B {\n" + " int i;\n" + " };\n" + " int j;\n" + "};\n" + "void f(std::vector& x) {\n" + " A::B b;\n" + " b.i = 123;\n" + " x.push_back(b);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("struct A {\n" + " struct B {\n" + " int i;\n" + " };\n" + " int j;\n" + "};\n" + "void f(std::vector& x) {\n" + " A::B b;\n" + " x.push_back(b);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: b\n", errout.str()); + + valueFlowUninit("struct A {\n" + " struct B {\n" + " int i;\n" + " };\n" + " int j;\n" + "};\n" + "void f(std::vector&x) {\n" + " A a;\n" + " a.j = 123;\n" + " x.push_back(a);\n" + "}\n"); + + valueFlowUninit("struct A {\n" + " struct B {\n" + " int i;\n" + " };\n" + " int j;\n" + "};\n" + "void f(std::vector& x) {\n" + " A a;\n" + " x.push_back(a);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: a\n", errout.str()); } void ctu_(const char* file, int line, const char code[]) {