diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 7ca512971..0df211fe6 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1170,6 +1170,13 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, bool noreturnIf = false; const bool initif = !alwaysTrue && checkScopeForVariable(scope, tok->next(), var, &possibleInitIf, &noreturnIf); + // bail out for such code: + // if (a) x=0; // conditional initialization + // if (b) return; // cppcheck doesn't know if b can be false when a is false. + // x++; // it's possible x is always initialized + if (!alwaysTrue && noreturnIf && number_of_if > 0) + return true; + std::map varValueIf; if (!initif) { for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 101c098c5..4cdf69afc 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2533,6 +2533,15 @@ private: " if (x || i>0) {}\n" // <- no error "}\n"); ASSERT_EQUALS("", errout.str()); + + // Unknown => bail out.. + checkUninitVar2("void f(int x) {\n" + " int i;\n" + " if (a(x)) i = 0;\n" + " if (b(x)) return;\n" + " i++;\n" // <- no error if b(x) is always true when a(x) is false + "}\n"); + ASSERT_EQUALS("", errout.str()); } };