From f34ff9325ae00dc2ee82ff9841471edf28274ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 29 Jun 2020 21:53:14 +0200 Subject: [PATCH] Fixed testrunner --- lib/astutils.cpp | 11 +++++++++++ lib/astutils.h | 1 + lib/exprengine.cpp | 4 ++-- lib/valueflow.cpp | 4 ++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index a4ed885b5..f1a13f961 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -440,6 +440,7 @@ bool extractForLoopValues(const Token *forToken, nonneg int * const varid, bool * const knownInitValue, MathLib::bigint * const initValue, + bool * const partialCond, MathLib::bigint * const stepValue, MathLib::bigint * const lastValue) { @@ -453,6 +454,16 @@ bool extractForLoopValues(const Token *forToken, *varid = initExpr->astOperand1()->varId(); *knownInitValue = initExpr->astOperand2()->hasKnownIntValue(); *initValue = (*knownInitValue) ? initExpr->astOperand2()->getKnownIntValue() : 0; + *partialCond = Token::Match(condExpr, "%oror%|&&"); + visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) { + if (Token::Match(tok, "%oror%|&&")) + return ChildrenToVisit::op1_and_op2; + if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == *varid && tok->astOperand2()->hasKnownIntValue()) { + if (Token::Match(condExpr, "%oror%|&&") || tok->astOperand2()->getKnownIntValue() < condExpr->astOperand2()->getKnownIntValue()) + condExpr = tok; + } + return ChildrenToVisit::none; + }); if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != *varid || !condExpr->astOperand2()->hasKnownIntValue()) return false; if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != *varid) diff --git a/lib/astutils.h b/lib/astutils.h index b9f88e251..a3545d3d7 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -115,6 +115,7 @@ bool extractForLoopValues(const Token *forToken, nonneg int * const varid, bool * const knownInitValue, long long * const initValue, + bool * const partialCond, long long * const stepValue, long long * const lastValue); diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 7991cebb4..0e96a97fb 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -2371,9 +2371,9 @@ static std::string execute(const Token *start, const Token *end, Data &data) if (Token::simpleMatch(tok, "for (")) { nonneg int varid; - bool hasKnownInitValue; + bool hasKnownInitValue, partialCond; MathLib::bigint initValue, stepValue, lastValue; - if (extractForLoopValues(tok, &varid, &hasKnownInitValue, &initValue, &stepValue, &lastValue) && hasKnownInitValue) { + if (extractForLoopValues(tok, &varid, &hasKnownInitValue, &initValue, &partialCond, &stepValue, &lastValue) && hasKnownInitValue && !partialCond) { auto loopValues = std::make_shared(data.getNewSymbolName(), initValue, lastValue); data.assignValue(tok, varid, loopValues); tok = tok->linkAt(1); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 0faa10ef5..60e644c14 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4626,10 +4626,10 @@ static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabas continue; nonneg int varid; - bool knownInitValue; + bool knownInitValue, partialCond; MathLib::bigint initValue, stepValue, lastValue; - if (extractForLoopValues(tok, &varid, &knownInitValue, &initValue, &stepValue, &lastValue)) { + if (extractForLoopValues(tok, &varid, &knownInitValue, &initValue, &partialCond, &stepValue, &lastValue)) { const bool executeBody = !knownInitValue || initValue <= lastValue; if (executeBody) { valueFlowForLoopSimplify(bodyStart, varid, false, initValue, tokenlist, errorLogger, settings);