Skip to content

Commit

Permalink
loop
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Feb 1, 2024
1 parent 4ca14a9 commit b80a193
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions lib/checkstl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3137,10 +3137,20 @@ void CheckStl::eraseIteratorOutOfBoundsError(const Token *ftok, const Token* ite
msg, CWE628, Certainty::normal);
}

static const ValueFlow::Value* getIterValue(const Token* tok, ValueFlow::Value::ValueType vt)
static const ValueFlow::Value* getOOBIterValue(const Token* tok, const ValueFlow::Value* sizeVal)
{
auto it = std::find_if(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.valueType == vt && (v.isPossible() || v.isKnown());
if (v.isPossible() || v.isKnown()) {
switch (v.valueType) {
case ValueFlow::Value::ValueType::ITERATOR_END:
return v.intvalue >= 0;
case ValueFlow::Value::ValueType::ITERATOR_START:
return (v.intvalue < 0) || (sizeVal && v.intvalue >= sizeVal->intvalue);
default:
break;
}
}
return false;
});
return it != tok->values().end() ? &*it : nullptr;
}
Expand All @@ -3161,22 +3171,11 @@ void CheckStl::eraseIteratorOutOfBounds()
if (action != Library::Container::Action::ERASE)
continue;
const std::vector<const Token*> args = getArguments(ftok);
if (args.size() != 1) // empty range is ok
if (args.size() != 1) // TODO: check range overload
continue;

const ValueFlow::Value* errVal = nullptr;
if (const ValueFlow::Value* endVal = getIterValue(args[0], ValueFlow::Value::ValueType::ITERATOR_END)) {
if (endVal->intvalue >= 0)
errVal = endVal;
}
else if (const ValueFlow::Value* startVal = getIterValue(args[0], ValueFlow::Value::ValueType::ITERATOR_START)) {
if (startVal->intvalue < 0)
errVal = startVal;
else if (const ValueFlow::Value* sizeVal = tok->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))
if (startVal->intvalue >= sizeVal->intvalue)
errVal = startVal;
}
if (errVal)
const ValueFlow::Value* sizeVal = tok->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE);
if (const ValueFlow::Value* errVal = getOOBIterValue(args[0], sizeVal))
eraseIteratorOutOfBoundsError(ftok, args[0], errVal);
}
}
Expand Down

0 comments on commit b80a193

Please sign in to comment.