9769: Improve value flow for ternary operator

In some cases, the condition of the ternary operator is assigned a known
value after the two possible results, and in such cases, we would not
take the opportunity to assign a value to the ternary operator (and to
the other parents in the ast).
This patch adds this capability.
This commit is contained in:
Ken-Patrick Lehrmann 2020-06-19 22:19:03 +02:00
parent 6743971112
commit 5a3789a23f
2 changed files with 17 additions and 0 deletions

View File

@ -524,6 +524,16 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
}
}
else if (parent->str() == "?" && value.isIntValue() && tok == parent->astOperand1() && value.isKnown() &&
parent->astOperand2() && parent->astOperand2()->astOperand1() && parent->astOperand2()->astOperand2()) {
const std::list<ValueFlow::Value> &values = (value.intvalue == 0
? parent->astOperand2()->astOperand2()->values()
: parent->astOperand2()->astOperand1()->values());
for (const ValueFlow::Value &v : values)
setTokenValue(parent, v, settings);
}
// Calculations..
else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp) || (parent->tokType() == Token::eLogicalOp)) &&
parent->astOperand1() &&

View File

@ -674,6 +674,13 @@ private:
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(123, values.empty() ? 0 : values.front().intvalue);
code = "int f() {\n"
" const int i = 1;\n"
" int x = i < 0 ? 0 : 1;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 1));
// ~
code = "x = ~0U;";
settings.platform(cppcheck::Platform::Native); // ensure platform is native