value flow: refactor. added Token::getMaxValue()

This commit is contained in:
Daniel Marjamäki 2014-01-21 16:58:23 +01:00
parent b91f42453b
commit 20b73747e0
2 changed files with 19 additions and 13 deletions

View File

@ -1157,25 +1157,19 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
}
else if (arrayInfo.num().size() == 1U && Token::Match(tok, "%varid% [", arrayInfo.declarationId()) && tok->next()->astOperand2() && !tok->next()->astOperand2()->values.empty()) {
const std::list<ValueFlow::Value> &values = tok->next()->astOperand2()->values;
std::list<ValueFlow::Value>::const_iterator it;
MathLib::bigint count = arrayInfo.num()[0];
const Token *parent = tok->next()->astParent();
while (parent && parent->str() == ".")
parent = tok->astParent();
if (parent && parent->str() == "&")
++count;
ValueFlow::Value errvalue, warnvalue;
for (it = values.begin(); it != values.end(); ++it) {
if (!it->condition && it->intvalue >= errvalue.intvalue)
errvalue = *it;
if (it->condition && it->intvalue >= warnvalue.intvalue)
warnvalue = *it;
}
if (errvalue.intvalue >= count)
arrayIndexOutOfBoundsError(tok, arrayInfo, errvalue);
if (_settings->isEnabled("warning") && warnvalue.intvalue >= count)
arrayIndexOutOfBoundsError(tok, arrayInfo, warnvalue);
const ValueFlow::Value *errvalue = tok->next()->astOperand2()->getMaxValue(false);
const ValueFlow::Value *warnvalue = tok->next()->astOperand2()->getMaxValue(true);
if (errvalue && errvalue->intvalue >= count)
arrayIndexOutOfBoundsError(tok, arrayInfo, *errvalue);
else if (_settings->isEnabled("warning") && warnvalue && warnvalue->intvalue >= count)
arrayIndexOutOfBoundsError(tok, arrayInfo, *warnvalue);
}
else if (Token::Match(tok, "%varid% [ %num% ]", arrayInfo.declarationId())) {

View File

@ -590,7 +590,19 @@ public:
return NULL;
}
const ValueFlow::Value * getMaxValue(bool condition) const {
const ValueFlow::Value *ret = 0;
std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
if ((!ret || it->intvalue > ret->intvalue) &&
((it->condition != NULL) == condition))
ret = &(*it);
}
return ret;
}
private:
void next(Token *nextToken) {
_next = nextToken;
}