parent
6397e29f84
commit
44f914eaee
|
@ -2030,11 +2030,15 @@ static ValueIterator removeAdjacentValues(std::list<ValueFlow::Value>& values, V
|
||||||
{
|
{
|
||||||
if (!isAdjacent(*x, **start))
|
if (!isAdjacent(*x, **start))
|
||||||
return std::next(x);
|
return std::next(x);
|
||||||
auto it = std::adjacent_find(start, last, [](ValueIterator x, ValueIterator y) { return !isAdjacent(*x, *y); });
|
auto it = std::adjacent_find(start, last, [](ValueIterator x, ValueIterator y) {
|
||||||
|
return !isAdjacent(*x, *y);
|
||||||
|
});
|
||||||
if (it == last)
|
if (it == last)
|
||||||
it--;
|
it--;
|
||||||
(*it)->bound = x->bound;
|
(*it)->bound = x->bound;
|
||||||
std::for_each(start, it, [&](ValueIterator y) { values.erase(y); });
|
std::for_each(start, it, [&](ValueIterator y) {
|
||||||
|
values.erase(y);
|
||||||
|
});
|
||||||
return values.erase(x);
|
return values.erase(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -374,7 +374,9 @@ static bool isZero(T x)
|
||||||
template <class R, class T>
|
template <class R, class T>
|
||||||
static R calculate(const std::string& s, const T& x, const T& y)
|
static R calculate(const std::string& s, const T& x, const T& y)
|
||||||
{
|
{
|
||||||
auto wrap = [](T z) { return R{z}; };
|
auto wrap = [](T z) {
|
||||||
|
return R{z};
|
||||||
|
};
|
||||||
switch (MathLib::encodeMultiChar(s)) {
|
switch (MathLib::encodeMultiChar(s)) {
|
||||||
case '+':
|
case '+':
|
||||||
return wrap(x + y);
|
return wrap(x + y);
|
||||||
|
@ -383,9 +385,11 @@ static R calculate(const std::string& s, const T& x, const T& y)
|
||||||
case '*':
|
case '*':
|
||||||
return wrap(x * y);
|
return wrap(x * y);
|
||||||
case '/':
|
case '/':
|
||||||
return isZero(y) ? R{} : wrap(x / y);
|
return isZero(y) ? R{} :
|
||||||
|
wrap(x / y);
|
||||||
case '%':
|
case '%':
|
||||||
return isZero(y) ? R{} : wrap(MathLib::bigint(x) % MathLib::bigint(y));
|
return isZero(y) ? R{} :
|
||||||
|
wrap(MathLib::bigint(x) % MathLib::bigint(y));
|
||||||
case '&':
|
case '&':
|
||||||
return wrap(MathLib::bigint(x) & MathLib::bigint(y));
|
return wrap(MathLib::bigint(x) & MathLib::bigint(y));
|
||||||
case '|':
|
case '|':
|
||||||
|
@ -397,9 +401,11 @@ static R calculate(const std::string& s, const T& x, const T& y)
|
||||||
case '<':
|
case '<':
|
||||||
return wrap(x < y);
|
return wrap(x < y);
|
||||||
case '<<':
|
case '<<':
|
||||||
return (y >= sizeof(MathLib::bigint) * 8) ? R{} : wrap(MathLib::bigint(x) << MathLib::bigint(y));
|
return (y >= sizeof(MathLib::bigint) * 8) ? R{} :
|
||||||
|
wrap(MathLib::bigint(x) << MathLib::bigint(y));
|
||||||
case '>>':
|
case '>>':
|
||||||
return (y >= sizeof(MathLib::bigint) * 8) ? R{} : wrap(MathLib::bigint(x) >> MathLib::bigint(y));
|
return (y >= sizeof(MathLib::bigint) * 8) ? R{} :
|
||||||
|
wrap(MathLib::bigint(x) >> MathLib::bigint(y));
|
||||||
case '&&':
|
case '&&':
|
||||||
return wrap(!isZero(x) && !isZero(y));
|
return wrap(!isZero(x) && !isZero(y));
|
||||||
case '||':
|
case '||':
|
||||||
|
|
|
@ -57,16 +57,14 @@ namespace ValueFlow {
|
||||||
|
|
||||||
struct less {
|
struct less {
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
bool operator()(const T& x, const U& y) const
|
bool operator()(const T& x, const U& y) const {
|
||||||
{
|
|
||||||
return x < y;
|
return x < y;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct adjacent {
|
struct adjacent {
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
bool operator()(const T& x, const U& y) const
|
bool operator()(const T& x, const U& y) const {
|
||||||
{
|
|
||||||
return std::abs(x - y) == 1;
|
return std::abs(x - y) == 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -163,22 +161,19 @@ namespace ValueFlow {
|
||||||
struct compareVisitor {
|
struct compareVisitor {
|
||||||
struct innerVisitor {
|
struct innerVisitor {
|
||||||
template <class Compare, class T, class U>
|
template <class Compare, class T, class U>
|
||||||
void operator()(bool& result, Compare compare, T x, U y) const
|
void operator()(bool& result, Compare compare, T x, U y) const {
|
||||||
{
|
|
||||||
result = compare(x, y);
|
result = compare(x, y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <class Compare, class T>
|
template <class Compare, class T>
|
||||||
void operator()(bool& result, const Value& rhs, Compare compare, T x) const
|
void operator()(bool& result, const Value& rhs, Compare compare, T x) const {
|
||||||
{
|
|
||||||
visitValue(rhs,
|
visitValue(rhs,
|
||||||
std::bind(innerVisitor{}, std::ref(result), std::move(compare), x, std::placeholders::_1));
|
std::bind(innerVisitor{}, std::ref(result), std::move(compare), x, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Compare>
|
template <class Compare>
|
||||||
bool compareValue(const Value& rhs, Compare compare) const
|
bool compareValue(const Value& rhs, Compare compare) const {
|
||||||
{
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
visitValue(
|
visitValue(
|
||||||
*this,
|
*this,
|
||||||
|
|
|
@ -5225,7 +5225,9 @@ private:
|
||||||
" return x + 0;\n"
|
" return x + 0;\n"
|
||||||
"}";
|
"}";
|
||||||
values = tokenValues(code, "+", &s);
|
values = tokenValues(code, "+", &s);
|
||||||
values.remove_if([](const ValueFlow::Value& v) { return v.isImpossible(); });
|
values.remove_if([](const ValueFlow::Value& v) {
|
||||||
|
return v.isImpossible();
|
||||||
|
});
|
||||||
ASSERT_EQUALS(2, values.size());
|
ASSERT_EQUALS(2, values.size());
|
||||||
ASSERT_EQUALS(0, values.front().intvalue);
|
ASSERT_EQUALS(0, values.front().intvalue);
|
||||||
ASSERT_EQUALS(100, values.back().intvalue);
|
ASSERT_EQUALS(100, values.back().intvalue);
|
||||||
|
|
Loading…
Reference in New Issue