diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e5018d735..d346e2a99 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -467,6 +467,11 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, varInfo->clear(); } + // goto => weird execution path + else if (tok->str() == "goto") { + varInfo->clear(); + } + // throw // TODO: if the execution leave the function then treat it as return else if (tok->str() == "throw") { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 10d3031a5..ae06ab199 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -61,6 +61,7 @@ private: // goto TEST_CASE(goto1); + TEST_CASE(goto2); // if/else TEST_CASE(ifelse1); @@ -324,6 +325,19 @@ private: ASSERT_EQUALS("", errout.str()); } + void goto2() { // #4231 + check("static char * f() {\n" + "x:\n" + " char *p = malloc(100);\n" + " if (err) {\n" + " free(p);\n" + " goto x;\n" + " }\n" + " return p;\n" // no error since there is a goto + "}"); + ASSERT_EQUALS("", errout.str()); + } + void ifelse1() { check("int f() {\n" " char *p = NULL;\n"