ValueFlow: Added utility functions getValueLE and getValueGE to simplify usage
This commit is contained in:
parent
f4cdb2c46a
commit
3c64c70ce2
|
@ -1182,17 +1182,9 @@ void CheckBufferOverrun::valueFlowCheckArrayIndex(const Token * const tok, const
|
|||
const Token *index = tok2->astOperand2();
|
||||
if (!index)
|
||||
continue;
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
const ValueFlow::Value *val = nullptr;
|
||||
for (it = index->values.begin(); it != index->values.end(); ++it) {
|
||||
if (it->intvalue < 0) {
|
||||
val = &*it;
|
||||
if (val->condition == nullptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (val && !val->condition)
|
||||
negativeIndexError(index, val->intvalue);
|
||||
const ValueFlow::Value *value = index->getValueLE(-1LL,_settings);
|
||||
if (value)
|
||||
negativeIndexError(index, *value);
|
||||
}
|
||||
|
||||
// Index out of bounds..
|
||||
|
@ -2046,6 +2038,15 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, MathLib::bigint in
|
|||
reportError(tok, Severity::error, "negativeIndex", ostr.str());
|
||||
}
|
||||
|
||||
void CheckBufferOverrun::negativeIndexError(const Token *tok, const ValueFlow::Value &index)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "Array index " << index.intvalue << " is out of bounds.";
|
||||
if (index.condition)
|
||||
ostr << " Otherwise there is useless condition at line " << index.condition->linenr() << ".";
|
||||
reportError(tok, index.condition ? Severity::warning : Severity::error, "negativeIndex", ostr.str(), index.inconclusive);
|
||||
}
|
||||
|
||||
CheckBufferOverrun::ArrayInfo::ArrayInfo()
|
||||
: _element_size(0), _declarationId(0)
|
||||
{
|
||||
|
|
|
@ -223,6 +223,7 @@ private:
|
|||
void terminateStrncpyError(const Token *tok, const std::string &varname);
|
||||
void bufferNotZeroTerminatedError(const Token *tok, const std::string &varname, const std::string &function);
|
||||
void negativeIndexError(const Token *tok, MathLib::bigint index);
|
||||
void negativeIndexError(const Token *tok, const ValueFlow::Value &index);
|
||||
void cmdLineArgsError(const Token *tok);
|
||||
void pointerOutOfBoundsError(const Token *tok, const std::string &object); // UB when result of calculation is out of bounds
|
||||
void arrayIndexThenCheckError(const Token *tok, const std::string &indexName);
|
||||
|
|
|
@ -3335,22 +3335,9 @@ void CheckOther::checkNegativeBitwiseShift()
|
|||
}
|
||||
|
||||
// Get negative rhs value. preferably a value which doesn't have 'condition'.
|
||||
const ValueFlow::Value *value = nullptr;
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = tok->astOperand2()->values.begin();
|
||||
it != tok->astOperand2()->values.end();
|
||||
++it) {
|
||||
if (it->intvalue < 0) {
|
||||
if (value == nullptr || it->condition == nullptr)
|
||||
value = &(*it);
|
||||
if (value->condition == nullptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
negativeBitwiseShiftError(tok);
|
||||
const ValueFlow::Value *value = tok->astOperand2()->getValueLE(-1LL, _settings);
|
||||
if (value)
|
||||
negativeBitwiseShiftError(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "token.h"
|
||||
#include "errorlogger.h"
|
||||
#include "check.h"
|
||||
#include "settings.h"
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -1278,3 +1279,46 @@ void Token::printValueFlow() const
|
|||
std::cout << "}" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Settings *settings) const
|
||||
{
|
||||
const ValueFlow::Value *ret = nullptr;
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
if (it->intvalue <= val) {
|
||||
if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
|
||||
ret = &(*it);
|
||||
if (!ret->inconclusive && !ret->condition)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (settings && ret) {
|
||||
if (ret->inconclusive && !settings->inconclusive)
|
||||
return nullptr;
|
||||
if (ret->condition && !settings->isEnabled("warning"))
|
||||
return nullptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Settings *settings) const
|
||||
{
|
||||
const ValueFlow::Value *ret = nullptr;
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
if (it->intvalue >= val) {
|
||||
if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
|
||||
ret = &(*it);
|
||||
if (!ret->inconclusive && !ret->condition)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (settings && ret) {
|
||||
if (ret->inconclusive && !settings->inconclusive)
|
||||
return nullptr;
|
||||
if (ret->condition && !settings->isEnabled("warning"))
|
||||
return nullptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
class Scope;
|
||||
class Function;
|
||||
class Variable;
|
||||
class Settings;
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
@ -619,6 +620,9 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
const ValueFlow::Value * getValueLE(const MathLib::bigint val, const Settings *settings) const;
|
||||
const ValueFlow::Value * getValueGE(const MathLib::bigint val, const Settings *settings) const;
|
||||
|
||||
private:
|
||||
|
||||
void next(Token *nextToken) {
|
||||
|
|
Loading…
Reference in New Issue