diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index f67621012..ff513b7fd 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -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 &values = tok->next()->astOperand2()->values; - std::list::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())) { diff --git a/lib/token.h b/lib/token.h index bb0aa3c56..bbc819267 100644 --- a/lib/token.h +++ b/lib/token.h @@ -590,7 +590,19 @@ public: return NULL; } + const ValueFlow::Value * getMaxValue(bool condition) const { + const ValueFlow::Value *ret = 0; + std::list::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; }