ValueFlow: Infer possible symbolic values (#4947)
This commit is contained in:
parent
7cded1967d
commit
ac14fd218b
|
@ -148,7 +148,8 @@ struct Interval {
|
||||||
result.setMinValue(minValue->intvalue + 1, minValue);
|
result.setMinValue(minValue->intvalue + 1, minValue);
|
||||||
if (minValue->isPossible() && minValue->bound == ValueFlow::Value::Bound::Lower)
|
if (minValue->isPossible() && minValue->bound == ValueFlow::Value::Bound::Lower)
|
||||||
result.setMinValue(minValue->intvalue, minValue);
|
result.setMinValue(minValue->intvalue, minValue);
|
||||||
if (minValue->isKnown())
|
if (!minValue->isImpossible() && minValue->bound == ValueFlow::Value::Bound::Point &&
|
||||||
|
std::count_if(values.begin(), values.end(), predicate) == 1)
|
||||||
return Interval::fromInt(minValue->intvalue, minValue);
|
return Interval::fromInt(minValue->intvalue, minValue);
|
||||||
}
|
}
|
||||||
const ValueFlow::Value* maxValue = getCompareValue(values, predicate, std::greater<MathLib::bigint>{});
|
const ValueFlow::Value* maxValue = getCompareValue(values, predicate, std::greater<MathLib::bigint>{});
|
||||||
|
|
|
@ -6767,8 +6767,6 @@ static void valueFlowInferCondition(TokenList* tokenlist,
|
||||||
if (result.size() != 1)
|
if (result.size() != 1)
|
||||||
continue;
|
continue;
|
||||||
ValueFlow::Value value = result.front();
|
ValueFlow::Value value = result.front();
|
||||||
value.intvalue = 1;
|
|
||||||
value.bound = ValueFlow::Value::Bound::Point;
|
|
||||||
setTokenValue(tok, std::move(value), settings);
|
setTokenValue(tok, std::move(value), settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ private:
|
||||||
TEST_CASE(zeroDiv15); // #8319
|
TEST_CASE(zeroDiv15); // #8319
|
||||||
TEST_CASE(zeroDiv16); // #11158
|
TEST_CASE(zeroDiv16); // #11158
|
||||||
TEST_CASE(zeroDiv17); // #9931
|
TEST_CASE(zeroDiv17); // #9931
|
||||||
|
TEST_CASE(zeroDiv18);
|
||||||
|
|
||||||
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
||||||
|
|
||||||
|
@ -652,6 +653,17 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zeroDiv18()
|
||||||
|
{
|
||||||
|
check("int f(int x, int y) {\n"
|
||||||
|
" if (x == y) {}\n"
|
||||||
|
" return 1 / (x-y);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==y' is redundant or there is division by zero at line 3.\n",
|
||||||
|
errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void zeroDivCond() {
|
void zeroDivCond() {
|
||||||
check("void f(unsigned int x) {\n"
|
check("void f(unsigned int x) {\n"
|
||||||
" int y = 17 / x;\n"
|
" int y = 17 / x;\n"
|
||||||
|
|
|
@ -5453,6 +5453,7 @@ private:
|
||||||
|
|
||||||
void valueFlowConditionExpressions() {
|
void valueFlowConditionExpressions() {
|
||||||
const char* code;
|
const char* code;
|
||||||
|
std::list<ValueFlow::Value> values;
|
||||||
|
|
||||||
// opposite condition
|
// opposite condition
|
||||||
code = "void f(int i, int j) {\n"
|
code = "void f(int i, int j) {\n"
|
||||||
|
@ -5559,7 +5560,11 @@ private:
|
||||||
" if (i != j) {}\n"
|
" if (i != j) {}\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ASSERT_EQUALS(true, removeImpossible(tokenValues(code, "!=")).empty());
|
values = removeImpossible(tokenValues(code, "!="));
|
||||||
|
ASSERT_EQUALS(1, values.size());
|
||||||
|
ASSERT_EQUALS(0, values.front().intvalue);
|
||||||
|
ASSERT_EQUALS(true, values.front().isIntValue());
|
||||||
|
ASSERT_EQUALS(true, values.front().isPossible());
|
||||||
|
|
||||||
code = "void f(bool b, int i, int j) {\n"
|
code = "void f(bool b, int i, int j) {\n"
|
||||||
" if (b || i == j) {} else {\n"
|
" if (b || i == j) {} else {\n"
|
||||||
|
|
Loading…
Reference in New Issue