Fixed #6911 (valueflow: comparison of string and NULL)

This commit is contained in:
Daniel Marjamäki 2015-08-02 18:12:03 +02:00
parent ea62ab337b
commit 8d3f7e36e9
2 changed files with 37 additions and 3 deletions

View File

@ -398,9 +398,13 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
parent->astOperand2()->values.front().isKnown())); parent->astOperand2()->values.front().isKnown()));
std::list<ValueFlow::Value>::const_iterator value1, value2; std::list<ValueFlow::Value>::const_iterator value1, value2;
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) { for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
if (value1->tokvalue && (!parent->isComparisonOp() || value1->tokvalue->type() != Token::eString))
continue;
for (value2 = parent->astOperand2()->values.begin(); value2 != parent->astOperand2()->values.end(); ++value2) { for (value2 = parent->astOperand2()->values.begin(); value2 != parent->astOperand2()->values.end(); ++value2) {
if (value2->tokvalue && (!parent->isComparisonOp() || value2->tokvalue->type() != Token::eString || value1->tokvalue))
continue;
if (known || value1->varId == 0U || value2->varId == 0U || if (known || value1->varId == 0U || value2->varId == 0U ||
(value1->varId == value2->varId && value1->varvalue == value2->varvalue)) { (value1->varId == value2->varId && value1->varvalue == value2->varvalue && !value1->tokvalue && !value2->tokvalue)) {
ValueFlow::Value result(0); ValueFlow::Value result(0);
result.condition = value1->condition ? value1->condition : value2->condition; result.condition = value1->condition ? value1->condition : value2->condition;
result.inconclusive = value1->inconclusive | value2->inconclusive; result.inconclusive = value1->inconclusive | value2->inconclusive;
@ -435,17 +439,25 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
break; break;
case '=': case '=':
if (parent->str() == "==") { if (parent->str() == "==") {
if (value1->tokvalue || value2->tokvalue)
result.intvalue = 0;
else
result.intvalue = value1->intvalue == value2->intvalue; result.intvalue = value1->intvalue == value2->intvalue;
setTokenValue(parent, result); setTokenValue(parent, result);
} }
break; break;
case '!': case '!':
if (parent->str() == "!=") { if (parent->str() == "!=") {
if (value1->tokvalue || value2->tokvalue)
result.intvalue = 1;
else
result.intvalue = value1->intvalue != value2->intvalue; result.intvalue = value1->intvalue != value2->intvalue;
setTokenValue(parent, result); setTokenValue(parent, result);
} }
break; break;
case '>': case '>':
if (value1->tokvalue || value2->tokvalue)
break;
if (parent->str() == ">") if (parent->str() == ">")
result.intvalue = value1->intvalue > value2->intvalue; result.intvalue = value1->intvalue > value2->intvalue;
else if (parent->str() == ">=") else if (parent->str() == ">=")
@ -455,6 +467,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
setTokenValue(parent, result); setTokenValue(parent, result);
break; break;
case '<': case '<':
if (value1->tokvalue || value2->tokvalue)
break;
if (parent->str() == "<") if (parent->str() == "<")
result.intvalue = value1->intvalue < value2->intvalue; result.intvalue = value1->intvalue < value2->intvalue;
else if (parent->str() == "<=") else if (parent->str() == "<=")

View File

@ -341,6 +341,26 @@ private:
ASSERT_EQUALS(2, values.front().intvalue); ASSERT_EQUALS(2, values.front().intvalue);
ASSERT_EQUALS(22, values.back().intvalue); ASSERT_EQUALS(22, values.back().intvalue);
} }
// Comparison of string
values = tokenValues("f(\"xyz\" == \"xyz\");", "=="); // implementation defined
ASSERT_EQUALS(0U, values.size()); // <- no value
values = tokenValues("f(\"xyz\" == 0);", "==");
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(0, values.front().intvalue);
values = tokenValues("f(0 == \"xyz\");", "==");
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(0, values.front().intvalue);
values = tokenValues("f(\"xyz\" != 0);", "!=");
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(1, values.front().intvalue);
values = tokenValues("f(0 != \"xyz\");", "!=");
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(1, values.front().intvalue);
} }
void valueFlowBeforeCondition() { void valueFlowBeforeCondition() {