From 6635e6cc07a2d60b76cef87588e2fd60919316b7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 17 Feb 2022 22:12:19 +0100 Subject: [PATCH] Fix #10795 cppcheckError with for loop (#3841) --- lib/valueflow.cpp | 10 +++++++--- test/testvalueflow.cpp | 11 +++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 17c4dd381..7ce2793b2 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6070,6 +6070,10 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, } } + const Token* vartok = expr; + const Token* rml = nextAfterAstRightmostLeaf(expr); + if (rml) + vartok = rml->previous(); if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings))) || @@ -6078,8 +6082,8 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings)))) break; - else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, expr->varId())) { - if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), expr->varId())) { + else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, vartok->varId())) { + if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), vartok->varId())) { if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); break; @@ -6088,7 +6092,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, bailout(tokenlist, errorLogger, tok2, "For loop variable skipping conditional scope"); tok2 = tok2->next()->link(); if (Token::simpleMatch(tok2, "} else {")) { - if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(2), expr->varId())) { + if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(2), vartok->varId())) { if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); break; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 5917dc4e9..5778e40c6 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4086,6 +4086,17 @@ private: "}\n"; value = valueOfTok(code, "x <"); ASSERT(!value.isKnown()); + + code = "void b(int* a) {\n" // #10795 + " for (*a = 1;;)\n" + " if (0) {}\n" + "}\n" + "struct S { int* a; }\n" + "void b(S& s) {\n" + " for (*s.a = 1;;)\n" + " if (0) {}\n" + "}\n"; + testValueOfX(code, 0, 0); // <- don't crash } void valueFlowSubFunction() {