Fix 10676: FP: Array index -1 is out of bounds. (#3670)
This commit is contained in:
parent
3524a0a3eb
commit
119ec0582a
2
Makefile
2
Makefile
|
@ -411,7 +411,7 @@ validateRules:
|
||||||
$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/path.h lib/platform.h lib/suppressions.h lib/utils.h
|
$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/path.h lib/platform.h lib/suppressions.h lib/utils.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/analyzerinfo.o $(libcppdir)/analyzerinfo.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/analyzerinfo.o $(libcppdir)/analyzerinfo.cpp
|
||||||
|
|
||||||
$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h
|
$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/astutils.o $(libcppdir)/astutils.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/astutils.o $(libcppdir)/astutils.cpp
|
||||||
|
|
||||||
$(libcppdir)/bughuntingchecks.o: lib/bughuntingchecks.cpp lib/astutils.h lib/bughuntingchecks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h
|
$(libcppdir)/bughuntingchecks.o: lib/bughuntingchecks.cpp lib/astutils.h lib/bughuntingchecks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "errortypes.h"
|
#include "errortypes.h"
|
||||||
|
#include "infer.h"
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "mathlib.h"
|
#include "mathlib.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "symboldatabase.h"
|
#include "symboldatabase.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "valueflow.h"
|
#include "valueflow.h"
|
||||||
|
#include "valueptr.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -687,9 +689,10 @@ bool extractForLoopValues(const Token *forToken,
|
||||||
const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2();
|
const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2();
|
||||||
if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
|
if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
|
||||||
return false;
|
return false;
|
||||||
|
std::vector<MathLib::bigint> minInitValue = getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values());
|
||||||
*varid = initExpr->astOperand1()->varId();
|
*varid = initExpr->astOperand1()->varId();
|
||||||
*knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
|
*knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
|
||||||
*initValue = (*knownInitValue) ? initExpr->astOperand2()->getKnownIntValue() : 0;
|
*initValue = minInitValue.empty() ? 0 : minInitValue.front();
|
||||||
*partialCond = Token::Match(condExpr, "%oror%|&&");
|
*partialCond = Token::Match(condExpr, "%oror%|&&");
|
||||||
visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) {
|
visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) {
|
||||||
if (Token::Match(tok, "%oror%|&&"))
|
if (Token::Match(tok, "%oror%|&&"))
|
||||||
|
|
|
@ -360,3 +360,16 @@ std::vector<ValueFlow::Value> infer(const ValuePtr<InferModel>& model,
|
||||||
{
|
{
|
||||||
return infer(model, op, std::move(lhsValues), {model->yield(rhs)});
|
return infer(model, op, std::move(lhsValues), {model->yield(rhs)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<MathLib::bigint> getMinValue(const ValuePtr<InferModel>& model, const std::list<ValueFlow::Value>& values)
|
||||||
|
{
|
||||||
|
return Interval::fromValues(values, [&](const ValueFlow::Value& v) {
|
||||||
|
return model->match(v);
|
||||||
|
}).minvalue;
|
||||||
|
}
|
||||||
|
std::vector<MathLib::bigint> getMaxValue(const ValuePtr<InferModel>& model, const std::list<ValueFlow::Value>& values)
|
||||||
|
{
|
||||||
|
return Interval::fromValues(values, [&](const ValueFlow::Value& v) {
|
||||||
|
return model->match(v);
|
||||||
|
}).maxvalue;
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,9 @@ std::vector<ValueFlow::Value> infer(const ValuePtr<InferModel>& model,
|
||||||
std::list<ValueFlow::Value> lhsValues,
|
std::list<ValueFlow::Value> lhsValues,
|
||||||
MathLib::bigint rhs);
|
MathLib::bigint rhs);
|
||||||
|
|
||||||
|
std::vector<MathLib::bigint> getMinValue(const ValuePtr<InferModel>& model, const std::list<ValueFlow::Value>& values);
|
||||||
|
std::vector<MathLib::bigint> getMaxValue(const ValuePtr<InferModel>& model, const std::list<ValueFlow::Value>& values);
|
||||||
|
|
||||||
std::string toString(const Interval& i);
|
std::string toString(const Interval& i);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2057,6 +2057,19 @@ private:
|
||||||
" return a[4 - x];\n"
|
" return a[4 - x];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("std::array<int,6> values;\n"
|
||||||
|
"int get_value();\n"
|
||||||
|
"int compute() {\n"
|
||||||
|
" int i = get_value();\n"
|
||||||
|
" if( i < 0 || i > 5)\n"
|
||||||
|
" return -1;\n"
|
||||||
|
" int sum = 0;\n"
|
||||||
|
" for( int j = i+1; j < 7; ++j)\n"
|
||||||
|
" sum += values[j-1];\n"
|
||||||
|
" return sum;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue