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)
|
if (tok->varId() == varid)
|
||||||
setTokenValue(tok, value);
|
setTokenValue(tok, value);
|
||||||
valueFlowAST(const_cast<Token*>(tok->astOperand1()), varid, 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);
|
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);
|
valueFlowAST(const_cast<Token*>(op2), varid, *it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip conditional expressions..
|
// Skip conditional expressions..
|
||||||
while (tok2->astOperand1() || tok2->astOperand2()) {
|
while (tok2->astOperand1() || tok2->astOperand2()) {
|
||||||
if (tok2->astOperand2())
|
if (tok2->astOperand2())
|
||||||
|
|
|
@ -838,6 +838,22 @@ private:
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\""));
|
ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\""));
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 9U, "\"\""));
|
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
|
// if/else
|
||||||
code = "void f() {\n"
|
code = "void f() {\n"
|
||||||
" int x = 123;\n"
|
" int x = 123;\n"
|
||||||
|
|
Loading…
Reference in New Issue