Fix 10625: False positive: known value below do while (#3623)

This commit is contained in:
Paul Fultz II 2021-12-15 12:32:14 -06:00 committed by GitHub
parent 6681576707
commit 5f73af0d0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 2 deletions

View File

@ -284,6 +284,10 @@ struct ForwardTraversal {
return Token::findsimplematch(endBlock->link(), "goto", endBlock); 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 { bool hasInnerReturnScope(const Token* start, const Token* end) const {
for (const Token* tok=start; tok != end; tok = tok->previous()) { for (const Token* tok=start; tok != end; tok = tok->previous()) {
if (Token::simpleMatch(tok, "}")) { if (Token::simpleMatch(tok, "}")) {
@ -404,7 +408,7 @@ struct ForwardTraversal {
bool checkElse = false; bool checkElse = false;
if (condTok && !Token::simpleMatch(condTok, ":")) if (condTok && !Token::simpleMatch(condTok, ":"))
std::tie(checkThen, checkElse) = evalCond(condTok, isDoWhile ? endBlock->previous() : nullptr); std::tie(checkThen, checkElse) = evalCond(condTok, isDoWhile ? endBlock->previous() : nullptr);
if (checkElse && exit) if (checkElse && exit && !hasJump(endBlock))
return Progress::Continue; return Progress::Continue;
Analyzer::Action bodyAnalysis = analyzeScope(endBlock); Analyzer::Action bodyAnalysis = analyzeScope(endBlock);
Analyzer::Action allAnalysis = bodyAnalysis; Analyzer::Action allAnalysis = bodyAnalysis;
@ -417,7 +421,7 @@ struct ForwardTraversal {
allAnalysis |= analyzeRecursive(stepTok); allAnalysis |= analyzeRecursive(stepTok);
actions |= allAnalysis; actions |= allAnalysis;
// do while(false) is not really a loop // do while(false) is not really a loop
if (checkElse && isDoWhile && if (checkElse && isDoWhile && !hasJump(endBlock) &&
(condTok->hasKnownIntValue() || (condTok->hasKnownIntValue() ||
(!bodyAnalysis.isModified() && !condAnalysis.isModified() && condAnalysis.isRead()))) { (!bodyAnalysis.isModified() && !condAnalysis.isModified() && condAnalysis.isRead()))) {
if (updateRange(endBlock->link(), endBlock) == Progress::Break) if (updateRange(endBlock->link(), endBlock) == Progress::Break)

View File

@ -4211,6 +4211,19 @@ private:
" return bFirst;\n" " return bFirst;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); 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() void alwaysTrueTryCatch()