Skip to content

Commit 39c5274

Browse files
authored
valueflow.cpp: optimized SingleValueFlowAnaylzer::isAlias() by avoidi… (#3051)
1 parent 8569a97 commit 39c5274

1 file changed

Lines changed: 77 additions & 5 deletions

File tree

lib/valueflow.cpp

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,8 +1662,81 @@ static bool evalAssignment(ValueFlow::Value &lhsValue, const std::string &assign
16621662
return true;
16631663
}
16641664

1665+
template<class T>
1666+
struct SingleRange {
1667+
T* x;
1668+
T* begin() const {
1669+
return x;
1670+
}
1671+
T* end() const {
1672+
return x+1;
1673+
}
1674+
};
1675+
1676+
template<class T>
1677+
SingleRange<T> MakeSingleRange(T& x)
1678+
{
1679+
return {&x};
1680+
}
1681+
1682+
class SelectValueFromVarIdMapRange {
1683+
using M = std::unordered_map<nonneg int, ValueFlow::Value>;
1684+
1685+
struct Iterator {
1686+
using iterator_category = std::forward_iterator_tag;
1687+
using value_type = const ValueFlow::Value;
1688+
using pointer = value_type *;
1689+
using reference = value_type &;
1690+
1691+
explicit Iterator(const M::const_iterator &it)
1692+
: mIt(it) {
1693+
}
1694+
1695+
reference operator*() const {
1696+
return mIt->second;
1697+
}
1698+
1699+
pointer operator->() {
1700+
return &mIt->second;
1701+
}
1702+
1703+
Iterator &operator++() {
1704+
// cppcheck-suppress postfixOperator - forward iterator needs to perform post-increment
1705+
mIt++;
1706+
return *this;
1707+
}
1708+
1709+
friend bool operator==(const Iterator &a, const Iterator &b) {
1710+
return a.mIt == b.mIt;
1711+
}
1712+
1713+
friend bool operator!=(const Iterator &a, const Iterator &b) {
1714+
return a.mIt != b.mIt;
1715+
}
1716+
1717+
private:
1718+
M::const_iterator mIt;
1719+
};
1720+
1721+
public:
1722+
explicit SelectValueFromVarIdMapRange(const M *m)
1723+
: mMap(m) {
1724+
}
1725+
1726+
Iterator begin() const {
1727+
return Iterator(mMap->begin());
1728+
}
1729+
Iterator end() const {
1730+
return Iterator(mMap->end());
1731+
}
1732+
1733+
private:
1734+
const M *mMap;
1735+
};
1736+
16651737
// Check if its an alias of the variable or is being aliased to this variable
1666-
static bool isAliasOf(const Variable * var, const Token *tok, nonneg int varid, const std::list<ValueFlow::Value>& values, bool* inconclusive = nullptr)
1738+
template<typename V>
1739+
static bool isAliasOf(const Variable * var, const Token *tok, nonneg int varid, const V& values, bool* inconclusive = nullptr)
16671740
{
16681741
if (tok->varId() == varid)
16691742
return false;
@@ -2101,7 +2174,7 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer {
21012174
const Variable* var = p.second;
21022175
if (tok->varId() == varid)
21032176
return true;
2104-
if (isAliasOf(var, tok, varid, {value}, &inconclusive))
2177+
if (isAliasOf(var, tok, varid, MakeSingleRange(value), &inconclusive))
21052178
return true;
21062179
}
21072180
}
@@ -4967,15 +5040,14 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
49675040
}
49685041

49695042
virtual bool isAlias(const Token* tok, bool& inconclusive) const OVERRIDE {
4970-
std::list<ValueFlow::Value> vals;
4971-
std::transform(values.begin(), values.end(), std::back_inserter(vals), SelectMapValues{});
5043+
const auto range = SelectValueFromVarIdMapRange(&values);
49725044

49735045
for (const auto& p:getVars()) {
49745046
nonneg int varid = p.first;
49755047
const Variable* var = p.second;
49765048
if (tok->varId() == varid)
49775049
return true;
4978-
if (isAliasOf(var, tok, varid, vals, &inconclusive))
5050+
if (isAliasOf(var, tok, varid, range, &inconclusive))
49795051
return true;
49805052
}
49815053
return false;

0 commit comments

Comments
 (0)