ValueFlow: dont set dynamic values in unreachable code (#6973)

This commit is contained in:
Daniel Marjamäki 2015-11-30 16:15:58 +01:00
parent 1b0bb02f1d
commit 8fb6f33aca
2 changed files with 33 additions and 9 deletions

View File

@ -1353,15 +1353,24 @@ static bool valueFlowForward(Token * const startToken,
const Token *op2 = tok2->astOperand2(); const Token *op2 = tok2->astOperand2();
if (!condition || !op2) // Ticket #6713 if (!condition || !op2) // Ticket #6713
continue; continue;
std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { if (condition->values.size() == 1U && condition->values.front().isKnown() && !condition->values.front().tokvalue) {
const ProgramMemory programMemory(getProgramMemory(tok2, varid, *it)); const ValueFlow::Value &condValue = condition->values.front();
if (conditionIsTrue(condition, programMemory)) const Token *expr = (condValue.intvalue != 0) ? op2->astOperand1() : op2->astOperand2();
valueFlowAST(const_cast<Token*>(op2->astOperand1()), varid, *it); std::list<ValueFlow::Value>::const_iterator it;
else if (conditionIsFalse(condition, programMemory)) for (it = values.begin(); it != values.end(); ++it)
valueFlowAST(const_cast<Token*>(op2->astOperand2()), varid, *it); valueFlowAST(const_cast<Token*>(expr), varid, *it);
else } else {
valueFlowAST(const_cast<Token*>(op2), varid, *it); std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
const ProgramMemory programMemory(getProgramMemory(tok2, varid, *it));
if (conditionIsTrue(condition, programMemory))
valueFlowAST(const_cast<Token*>(op2->astOperand1()), varid, *it);
else if (conditionIsFalse(condition, programMemory))
valueFlowAST(const_cast<Token*>(op2->astOperand2()), varid, *it);
else
valueFlowAST(const_cast<Token*>(op2), varid, *it);
}
} }
// Skip conditional expressions.. // Skip conditional expressions..
while (tok2->astOperand1() || tok2->astOperand2()) { while (tok2->astOperand1() || tok2->astOperand2()) {

View File

@ -805,6 +805,21 @@ private:
"}\n"; "}\n";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
// ?:
code = "void f() {\n"
" int x = 8;\n"
" a = ((x > 10) ?\n"
" x : 0);\n" // <- x is not 8
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 8));
code = "void f() {\n" // #6973
" char *x = \"\";\n"
" a = ((x[0] == 'U') ?\n"
" x[1] : 0);\n" // <- x is not ""
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, "\"\""));
// if/else // if/else
code = "void f() {\n" code = "void f() {\n"
" int x = 123;\n" " int x = 123;\n"