diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 4ed0a6d7e26..e4e348fbf3b 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -418,9 +418,15 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var continue; } - // assignment with nonzero constant.. - if (Token::Match(tok->previous(), "[;{}] %var% = - %name% ;")) - variableValue[tok->varId()] = !VariableValue(0); + // track values of other variables.. + if (Token::Match(tok->previous(), "[;{}] %var% =")) { + if (tok->next()->astOperand2() && tok->next()->astOperand2()->hasKnownIntValue()) + variableValue[tok->varId()] = VariableValue(tok->next()->astOperand2()->getKnownIntValue()); + else if (Token::Match(tok->previous(), "[;{}] %var% = - %name% ;")) + variableValue[tok->varId()] = !VariableValue(0); + else + variableValue.erase(tok->varId()); + } // Inner scope.. else if (Token::simpleMatch(tok, "if (")) { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6ce2ce41c11..49f77695ce1 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -4743,6 +4743,20 @@ class TestUninitVar : public TestFixture { " char* q = (s).p;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // if with flag + checkUninitVar("struct AB { int a; int b; };\n" + "int f(int x) {\n" + " struct AB ab;\n" + " int flag = 0;\n" + " if (x == 0) {\n" + " flag = dostuff(&ab);\n" + " }\n" + " if (flag) {\n" + " a = ab.a;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void uninitvar2_while() {