Fixed #6911 (valueflow: comparison of string and NULL)
This commit is contained in:
parent
ea62ab337b
commit
8d3f7e36e9
|
@ -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() == "==") {
|
||||||
result.intvalue = value1->intvalue == value2->intvalue;
|
if (value1->tokvalue || value2->tokvalue)
|
||||||
|
result.intvalue = 0;
|
||||||
|
else
|
||||||
|
result.intvalue = value1->intvalue == value2->intvalue;
|
||||||
setTokenValue(parent, result);
|
setTokenValue(parent, result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
if (parent->str() == "!=") {
|
if (parent->str() == "!=") {
|
||||||
result.intvalue = value1->intvalue != value2->intvalue;
|
if (value1->tokvalue || value2->tokvalue)
|
||||||
|
result.intvalue = 1;
|
||||||
|
else
|
||||||
|
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() == "<=")
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue