From 36513ef7af1e94c847ed73f88532edd174751b25 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:32:02 +0100 Subject: [PATCH] Fix #12848 FP: null pointer dereference in while loop (#7048) --- lib/valueflow.cpp | 2 +- test/testvalueflow.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 98a0c087d35..f551d82221f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4461,7 +4461,7 @@ struct ConditionHandler { if (!Token::Match(tok, "%assign%|++|--") && findExpression(cond.vartok->exprId(), start, end, [&](const Token* tok2) { return Token::Match(tok2->astParent(), "%assign%") && astIsLHS(tok2); - })) { + }) && !findEscapeStatement(block->scope(), &settings.library)) { // Start at the end of the loop body Token* bodyTok = top->link()->next(); reverse(bodyTok->link(), bodyTok, cond.vartok, values, tokenlist, errorLogger, settings); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 5b4b4613221..d26b339629d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1820,6 +1820,23 @@ class TestValueFlow : public TestFixture { " }\n" "}"; ASSERT_EQUALS(false, testValueOfX(code, 2U, 0)); + + code = "struct S {\n" // #12848 + " S* next;\n" + " int a;\n" + "};\n" + "void f(S* x, int i) {\n" + " while (x) {\n" + " if (x->a == 0) {\n" + " x = x->next;\n" + " continue;\n" + " }\n" + " if (i == 0)\n" + " break;\n" + " x->a = i--;\n" + " }\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 13U, 0)); } void valueFlowBeforeConditionTernaryOp() { // bailout: ?: