From ef1f3fbee6b66b1127276997ba1bfb4859a35f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 14 Sep 2017 22:49:47 +0200 Subject: [PATCH] Fixed #8173 (ValueFlow: use AST when setting values in assignment RHS ((n=42) && n=='A')) --- lib/valueflow.cpp | 24 ++++++++++++++++-------- test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 069df71f5..caea5a12c 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1819,16 +1819,24 @@ static bool valueFlowForward(Token * const startToken, // bailout: assignment else if (Token::Match(tok2->previous(), "!!* %name% %assign%")) { // simplify rhs - for (Token *tok3 = tok2->tokAt(2); tok3; tok3 = tok3->next()) { - if (tok3->varId() == varid) { + std::stack rhs; + rhs.push(const_cast(tok2->next()->astOperand2())); + while (!rhs.empty()) { + Token *rtok = rhs.top(); + rhs.pop(); + if (!rtok) + continue; + if (rtok->str() == "(" && Token::Match(rtok->astOperand1(), "sizeof|typeof|typeid")) + continue; + if (Token::Match(rtok, "++|--|?|:|;|,")) + continue; + if (rtok->varId() == varid) { std::list::const_iterator it; for (it = values.begin(); it != values.end(); ++it) - setTokenValue(tok3, *it, settings); - } else if (Token::Match(tok3, "++|--|?|:|;|,")) - break; - // Skip sizeof etc - else if (Token::Match(tok3, "sizeof|typeof|typeid (")) - tok3 = tok3->linkAt(1); + setTokenValue(rtok, *it, settings); + } + rhs.push(const_cast(rtok->astOperand1())); + rhs.push(const_cast(rtok->astOperand2())); } if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str()); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 0add92f2e..d03edae48 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -2646,6 +2646,14 @@ private: "}"; values = tokenValues(code, "x ; }"); ASSERT_EQUALS(true, values.empty()); + + // return (#8173) + code = "int repeat() {\n" + " const char *n;\n" + " return((n=42) && *n == 'A');\n" + "}"; + values = tokenValues(code, "n =="); + ASSERT_EQUALS(true, values.size() != 1U || !values.front().isUninitValue()); } };