Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ $(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib
$(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp

$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h
$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp

$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
Expand All @@ -690,7 +690,7 @@ $(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h
$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp

$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h
$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp

$(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h
Expand Down Expand Up @@ -957,7 +957,7 @@ test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/
test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp

test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vf_common.h lib/vfvalue.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp

test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
Expand Down
56 changes: 45 additions & 11 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <functional>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <list>
#include <set>
#include <type_traits>
Expand Down Expand Up @@ -955,29 +956,58 @@ bool extractForLoopValues(const Token *forToken,
nonneg int &varid,
bool &knownInitValue,
MathLib::bigint &initValue,
const ValueFlow::Value*& initValueSource,
const ValueFlow::Value*& initValueWitnessSource,
bool &partialCond,
MathLib::bigint &stepValue,
MathLib::bigint &lastValue)
{
initValueSource = nullptr;
initValueWitnessSource = nullptr;
if (!Token::simpleMatch(forToken, "for (") || !Token::simpleMatch(forToken->next()->astOperand2(), ";"))
return false;
const Token *initExpr = forToken->next()->astOperand2()->astOperand1();
const Token *condExpr = forToken->next()->astOperand2()->astOperand2()->astOperand1();
const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2();
if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
return false;
std::vector<MathLib::bigint> minInitValue =
getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values());
const Token* const initToken = initExpr->astOperand2();
const std::vector<MathLib::bigint> minInitValue =
getMinValue(makeIntegralInferModel(), initToken->values(), &initValueSource);
if (minInitValue.empty()) {
const ValueFlow::Value* v = initExpr->astOperand2()->getMinValue(true);
if (v)
minInitValue.push_back(v->intvalue);
knownInitValue = false;
initValue = 0;
} else {
knownInitValue = initToken->hasKnownIntValue();
initValue = minInitValue.front();
if (knownInitValue && initValueSource && initValueSource->bound != ValueFlow::Value::Bound::Point) {
const auto it = std::find_if(initToken->values().cbegin(),
initToken->values().cend(),
[initValue](const ValueFlow::Value& value) {
return value.isIntValue() && !value.isImpossible() && !value.isInconclusive() &&
value.bound == ValueFlow::Value::Bound::Point && value.intvalue == initValue;
});
if (it != initToken->values().cend())
initValueSource = &*it;
}
}
if (minInitValue.empty())
const auto isNegativeEvidence = [](const ValueFlow::Value& candidate) {
return candidate.isIntValue() && !candidate.isImpossible() && !candidate.isInconclusive() &&
(candidate.isKnown() || candidate.isPossible()) && candidate.path >= 0 && candidate.intvalue < 0 &&
(candidate.bound == ValueFlow::Value::Bound::Point || candidate.bound == ValueFlow::Value::Bound::Upper);
};
if (initValueSource && isNegativeEvidence(*initValueSource)) {
initValueWitnessSource = initValueSource;
} else {
const auto it = std::find_if(initToken->values().cbegin(),
initToken->values().cend(),
isNegativeEvidence);
if (it != initToken->values().cend())
initValueWitnessSource = &*it;
}
if (minInitValue.empty() && !initValueWitnessSource)
return false;
varid = initExpr->astOperand1()->varId();
knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
initValue = minInitValue.front();
partialCond = Token::Match(condExpr, "%oror%|&&");
visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) {
if (Token::Match(tok, "%oror%|&&"))
Expand All @@ -993,10 +1023,14 @@ bool extractForLoopValues(const Token *forToken,
if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != varid)
return false;
stepValue = 1;
if (condExpr->str() == "<")
lastValue = condExpr->astOperand2()->getKnownIntValue() - 1;
else
if (condExpr->str() == "<") {
const MathLib::bigint limit = condExpr->astOperand2()->getKnownIntValue();
if (limit == std::numeric_limits<MathLib::bigint>::min())
return false;
lastValue = limit - 1;
} else {
lastValue = condExpr->astOperand2()->getKnownIntValue();
}
return true;
}

Expand Down
6 changes: 5 additions & 1 deletion lib/astutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,16 @@ const Token* getCondTokFromEnd(const Token* endBlock);
const Token *findNextTokenFromBreak(const Token *breakToken);

/**
* Extract for loop values: loopvar varid, init value, step value, last value (inclusive)
* Extract for loop values: loopvar varid, init value, step value, last value (inclusive).
* `initValueSource` identifies the fact supplying the minimum; `initValueWitnessSource`
* identifies an actual negative point or upper bound, if present.
*/
bool extractForLoopValues(const Token *forToken,
nonneg int &varid,
bool &knownInitValue,
MathLib::bigint &initValue,
const ValueFlow::Value*& initValueSource,
const ValueFlow::Value*& initValueWitnessSource,
bool &partialCond,
MathLib::bigint &stepValue,
MathLib::bigint &lastValue);
Expand Down
1 change: 1 addition & 0 deletions lib/checkbufferoverrun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ void CheckBufferOverrunImpl::arrayIndex()
arrayIndexError(tok, dimensions, indexValues);
}


// Negative index
bool neg = false;
std::vector<ValueFlow::Value> negativeIndexes;
Expand Down
Loading
Loading