MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / extractForLoopValues

Function extractForLoopValues

lib/astutils.cpp:956–1003  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

954}
955
956bool extractForLoopValues(const Token *forToken,
957 nonneg int &varid,
958 bool &knownInitValue,
959 MathLib::bigint &initValue,
960 bool &partialCond,
961 MathLib::bigint &stepValue,
962 MathLib::bigint &lastValue)
963{
964 if (!Token::simpleMatch(forToken, "for (") || !Token::simpleMatch(forToken->next()->astOperand2(), ";"))
965 return false;
966 const Token *initExpr = forToken->next()->astOperand2()->astOperand1();
967 const Token *condExpr = forToken->next()->astOperand2()->astOperand2()->astOperand1();
968 const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2();
969 if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
970 return false;
971 std::vector<MathLib::bigint> minInitValue =
972 getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values());
973 if (minInitValue.empty()) {
974 const ValueFlow::Value* v = initExpr->astOperand2()->getMinValue(true);
975 if (v)
976 minInitValue.push_back(v->intvalue);
977 }
978 if (minInitValue.empty())
979 return false;
980 varid = initExpr->astOperand1()->varId();
981 knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
982 initValue = minInitValue.front();
983 partialCond = Token::Match(condExpr, "%oror%|&&");
984 visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) {
985 if (Token::Match(tok, "%oror%|&&"))
986 return ChildrenToVisit::op1_and_op2;
987 if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == varid && tok->astOperand2()->hasKnownIntValue()) {
988 if (Token::Match(condExpr, "%oror%|&&") || tok->astOperand2()->getKnownIntValue() < condExpr->astOperand2()->getKnownIntValue())
989 condExpr = tok;
990 }
991 return ChildrenToVisit::none;
992 });
993 if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != varid || !condExpr->astOperand2()->hasKnownIntValue())
994 return false;
995 if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != varid)
996 return false;
997 stepValue = 1;
998 if (condExpr->str() == "<")
999 lastValue = condExpr->astOperand2()->getKnownIntValue() - 1;
1000 else
1001 lastValue = condExpr->astOperand2()->getKnownIntValue();
1002 return true;
1003}
1004
1005
1006static const Token * getVariableInitExpression(const Variable * var)

Callers 1

valueFlowForLoopFunction · 0.85

Calls 15

getMinValueFunction · 0.85
makeIntegralInferModelFunction · 0.85
visitAstNodesFunction · 0.85
astOperand2Method · 0.80
nextMethod · 0.80
astOperand1Method · 0.80
isBinaryOpMethod · 0.80
getMinValueMethod · 0.80
frontMethod · 0.80
getKnownIntValueMethod · 0.80
isUnaryOpMethod · 0.80
simpleMatchFunction · 0.70

Tested by

no test coverage detected