diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 2209a2625..09caf41d0 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1649,7 +1649,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp } } - if (Token::Match(vartok->previous(), "++|--|?|:|%cop%")) { + if (Token::Match(vartok->previous(), "++|--|%cop%")) { if (cpp && vartok->previous()->str() == ">>") { // assume that variable is initialized return false; @@ -1688,6 +1688,23 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp if (Token::Match(vartok->previous(), "= %var% ;|%cop%")) return true; + if (Token::Match(vartok->previous(), "? %var%")) { + // this is only variable usage if variable is either: + // * unconditionally uninitialized + // * used in both rhs and lhs of ':' operator + bool rhs = false; + for (const Token *tok2 = vartok; tok2; tok2 = tok2->next()) { + if (tok2->str() == "(") + tok2 = tok2->link(); + else if (tok2->str() == ":") + rhs = true; + else if (Token::Match(tok2, "[)];,{}]")) + break; + else if (rhs && tok2->varId() == vartok->varId()) + return true; + } + } + bool unknown = false; if (pointer && CheckNullPointer::isPointerDeRef(vartok, unknown)) { // function parameter? diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index cd4ea6441..36552fc57 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2143,6 +2143,13 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + checkUninitVar2("int f(int a) {\n" + " int x;\n" + " if (a==3) { x=2; }\n" + " y = (a==3) ? x : a;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // = { .. } checkUninitVar2("int f() {\n" " int a;\n"