diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ccf070f17..93e2b7872 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -329,6 +329,40 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value) setTokenValue(parent,value); } + else if (parent->str() == ":") { + setTokenValue(parent,value); + } + + else if (parent->str() == "?") { + // is condition only depending on 1 variable? + std::stack tokens; + tokens.push(parent->astOperand1()); + std::set variables; // used variables + while (!tokens.empty()) { + const Token *t = tokens.top(); + tokens.pop(); + if (!t) + continue; + tokens.push(t->astOperand1()); + tokens.push(t->astOperand2()); + if (t->varId()) { + variables.insert(t->varId()); + if (variables.size() > 1U || value.varId != 0U) + return; + } else if (t->str() == "(" && Token::Match(t->previous(), "%name%")) + return; // function call + } + + ValueFlow::Value v(value); + + if (!variables.empty()) { + v.varId = *(variables.begin()); + return; + } + + setTokenValue(parent, v); + } + // Calculations.. else if (parent->isArithmeticalOp() && parent->astOperand1() && parent->astOperand2()) { std::list::const_iterator value1, value2; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index b70580dc1..f2fac5226 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -253,6 +253,13 @@ private: ASSERT_EQUALS(4, values.front().intvalue); ASSERT_EQUALS(16, values.back().intvalue); + // ? : + code = "x = y ? 2 : 3;\n"; + values = tokenValues(code,"?"); + ASSERT_EQUALS(2U, values.size()); + ASSERT_EQUALS(2, values.front().intvalue); + ASSERT_EQUALS(3, values.back().intvalue); + // function call => calculation code = "void f(int x) {\n" " a = x + 8;\n"