ValueFlow: Added utility functions getValueLE and getValueGE to simplify usage

This commit is contained in:
Daniel Marjamäki 2014-04-02 06:49:28 +02:00
parent f4cdb2c46a
commit 3c64c70ce2
5 changed files with 64 additions and 27 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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) {