From 5f73af0d0ef14a11879c6ff44fa02e5b019be42c Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 15 Dec 2021 12:32:14 -0600 Subject: [PATCH] Fix 10625: False positive: known value below do while (#3623) --- lib/forwardanalyzer.cpp | 8 ++++++-- test/testcondition.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 19cd196df..f6fbbf949 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -284,6 +284,10 @@ struct ForwardTraversal { return Token::findsimplematch(endBlock->link(), "goto", endBlock); } + bool hasJump(const Token* endBlock) { + return Token::findmatch(endBlock->link(), "goto|break", endBlock); + } + bool hasInnerReturnScope(const Token* start, const Token* end) const { for (const Token* tok=start; tok != end; tok = tok->previous()) { if (Token::simpleMatch(tok, "}")) { @@ -404,7 +408,7 @@ struct ForwardTraversal { bool checkElse = false; if (condTok && !Token::simpleMatch(condTok, ":")) std::tie(checkThen, checkElse) = evalCond(condTok, isDoWhile ? endBlock->previous() : nullptr); - if (checkElse && exit) + if (checkElse && exit && !hasJump(endBlock)) return Progress::Continue; Analyzer::Action bodyAnalysis = analyzeScope(endBlock); Analyzer::Action allAnalysis = bodyAnalysis; @@ -417,7 +421,7 @@ struct ForwardTraversal { allAnalysis |= analyzeRecursive(stepTok); actions |= allAnalysis; // do while(false) is not really a loop - if (checkElse && isDoWhile && + if (checkElse && isDoWhile && !hasJump(endBlock) && (condTok->hasKnownIntValue() || (!bodyAnalysis.isModified() && !condAnalysis.isModified() && condAnalysis.isRead()))) { if (updateRange(endBlock->link(), endBlock) == Progress::Break) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 8d66c8e2e..50fde0d5a 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4211,6 +4211,19 @@ private: " return bFirst;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " void * pool = NULL;\n" + " do {\n" + " pool = malloc(40);\n" + " if (dostuff())\n" + " break;\n" + " pool = NULL;\n" + " }\n" + " while (0);\n" + " if (pool) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void alwaysTrueTryCatch()