diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e26494a01..46e0d0f2a 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -284,7 +284,7 @@ static const Token * isFunctionCall(const Token * nameToken) return nullptr; } -void CheckLeakAutoVar::checkScope(const Token * const startToken, +bool CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, std::set notzero, nonneg int recursiveCount) @@ -532,10 +532,12 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, return ChildrenToVisit::none; }); - checkScope(closingParenthesis->next(), &varInfo1, notzero, recursiveCount); + if (!checkScope(closingParenthesis->next(), &varInfo1, notzero, recursiveCount)) + continue; closingParenthesis = closingParenthesis->linkAt(1); if (Token::simpleMatch(closingParenthesis, "} else {")) { - checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount); + if (!checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount)) + continue; tok = closingParenthesis->linkAt(2)->previous(); } else { tok = closingParenthesis->previous(); @@ -675,6 +677,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, // goto => weird execution path else if (tok->str() == "goto") { varInfo->clear(); + return false; } // continue/break @@ -765,6 +768,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, } } ret(endToken, *varInfo, true); + return true; } diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index 8fa720ab9..15b8a287a 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -125,7 +125,7 @@ private: void check(); /** check for leaks in a function scope */ - void checkScope(const Token * const startToken, + bool checkScope(const Token * const startToken, VarInfo *varInfo, std::set notzero, nonneg int recursiveCount); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 584135a04..01ceb111d 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -1241,8 +1241,8 @@ private: ASSERT_EQUALS("", errout.str()); } - void doublefree4() { // #5451 - exit - check("void f(char *p) {\n" + void doublefree4() { + check("void f(char *p) {\n" // #5451 - exit " if (x) {\n" " free(p);\n" " exit(1);\n" @@ -1250,6 +1250,17 @@ private: " free(p);\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("void f(void* p, int i) {\n" // #11391 + " if (i)\n" + " goto cleanup;\n" + " free(p);\n" + " exit(0);\n" + "cleanup:\n" + " free(p);\n" + " exit(1);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void doublefree5() { // #5522