Fix #10795 cppcheckError with for loop (#3841)

This commit is contained in:
chrchr-github 2022-02-17 22:12:19 +01:00 committed by GitHub
parent 2f46e57311
commit 6635e6cc07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 3 deletions

View File

@ -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() == "&&" && if ((tok2->str() == "&&" &&
conditionIsFalse(tok2->astOperand1(), conditionIsFalse(tok2->astOperand1(),
getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings))) || 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)))) getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings))))
break; break;
else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, 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), expr->varId())) { if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), vartok->varId())) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return");
break; break;
@ -6088,7 +6092,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart,
bailout(tokenlist, errorLogger, tok2, "For loop variable skipping conditional scope"); bailout(tokenlist, errorLogger, tok2, "For loop variable skipping conditional scope");
tok2 = tok2->next()->link(); tok2 = tok2->next()->link();
if (Token::simpleMatch(tok2, "} else {")) { 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) if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return");
break; break;

View File

@ -4086,6 +4086,17 @@ private:
"}\n"; "}\n";
value = valueOfTok(code, "x <"); value = valueOfTok(code, "x <");
ASSERT(!value.isKnown()); 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() { void valueFlowSubFunction() {