Fixed #7599 (valueFlowAST: handle && and || better)
This commit is contained in:
parent
0162f33d3f
commit
4f051bf9dd
|
@ -1069,6 +1069,23 @@ static void valueFlowAST(Token *tok, unsigned int varid, const ValueFlow::Value
|
|||
if (tok->varId() == varid)
|
||||
setTokenValue(tok, value);
|
||||
valueFlowAST(const_cast<Token*>(tok->astOperand1()), varid, value);
|
||||
if (tok->str() == "&&" && tok->astOperand1() && tok->astOperand1()->getValue(0)) {
|
||||
ProgramMemory pm;
|
||||
pm.setValue(varid,value);
|
||||
if (conditionIsFalse(tok->astOperand1(), pm))
|
||||
return;
|
||||
} else if (tok->str() == "||" && tok->astOperand1()) {
|
||||
bool nonzero = false;
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = tok->astOperand1()->values.begin(); it != tok->astOperand1()->values.end(); ++it) {
|
||||
nonzero |= (it->intvalue != 0);
|
||||
}
|
||||
if (!nonzero)
|
||||
return;
|
||||
ProgramMemory pm;
|
||||
pm.setValue(varid,value);
|
||||
if (conditionIsTrue(tok->astOperand1(), pm))
|
||||
return;
|
||||
}
|
||||
valueFlowAST(const_cast<Token*>(tok->astOperand2()), varid, value);
|
||||
}
|
||||
|
||||
|
@ -1446,6 +1463,7 @@ static bool valueFlowForward(Token * const startToken,
|
|||
valueFlowAST(const_cast<Token*>(op2), varid, *it);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip conditional expressions..
|
||||
while (tok2->astOperand1() || tok2->astOperand2()) {
|
||||
if (tok2->astOperand2())
|
||||
|
|
|
@ -838,6 +838,22 @@ private:
|
|||
ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\""));
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 9U, "\"\""));
|
||||
|
||||
code = "void f() {\n" // #7599
|
||||
" t *x = 0;\n"
|
||||
" y = (a ? 1 : x\n" // <- x is 0
|
||||
" && x->y ? 1 : 2);" // <- x is not 0
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
|
||||
|
||||
code = "void f() {\n" // #7599
|
||||
" t *x = 0;\n"
|
||||
" y = (a ? 1 : !x\n" // <- x is 0
|
||||
" || x->y ? 1 : 2);" // <- x is not 0
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
|
||||
|
||||
// if/else
|
||||
code = "void f() {\n"
|
||||
" int x = 123;\n"
|
||||
|
|
Loading…
Reference in New Issue