Fixed #2014 (False positive with longjmp)

This commit is contained in:
Daniel Marjamäki 2010-09-03 07:18:01 +02:00
parent b5276ce9e5
commit fb4fce466e
4 changed files with 52 additions and 5 deletions

View File

@ -1360,6 +1360,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
} }
// Calling setjmp / longjmp => bail out
else if (Token::Match(tok, "setjmp|longjmp"))
{
while (rethead->next())
rethead->deleteNext();
return rethead;
}
// Inside class function.. if the var is passed as a parameter then // Inside class function.. if the var is passed as a parameter then
// just add a "::use" // just add a "::use"
// The "::use" means that a member function was probably called but it wasn't analyzed further // The "::use" means that a member function was probably called but it wasn't analyzed further

View File

@ -76,13 +76,13 @@ void ExecutionPath::print() const
} }
// I use this function when debugging ExecutionPaths with GDB // I use this function when debugging ExecutionPaths with GDB
#ifdef __GNUC__ /*
static void printchecks(const std::list<ExecutionPath *> &checks) static void printchecks(const std::list<ExecutionPath *> &checks)
{ {
for (std::list<ExecutionPath *>::const_iterator it = checks.begin(); it != checks.end(); ++it) for (std::list<ExecutionPath *>::const_iterator it = checks.begin(); it != checks.end(); ++it)
(*it)->print(); (*it)->print();
} }
#endif */
@ -176,8 +176,8 @@ static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &c
} }
} }
// goto => bailout // goto/setjmp/longjmp => bailout
if (tok->str() == "goto") if (Token::Match(tok, "goto|setjmp|longjmp"))
{ {
ExecutionPath::bailOut(checks); ExecutionPath::bailOut(checks);
return; return;

View File

@ -403,6 +403,9 @@ private:
// #1440 - Check function parameters also.. // #1440 - Check function parameters also..
TEST_CASE(functionParameter); TEST_CASE(functionParameter);
// setjmp/longjmp..
TEST_CASE(jmp);
} }
@ -2913,6 +2916,30 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str());
} }
// Ticket #2014 - setjmp / longjmp
void jmp()
{
check("int main()\n"
"{\n"
" jmp_buf env;\n"
" int val;\n"
" char *a;\n"
"\n"
" val = setjmp(env);\n"
" if(val)\n"
" {\n"
" delete a;\n"
" return 0;\n"
" }\n"
"\n"
" a = new char(1);\n"
" longjmp(env, 1);\n"
"\n"
" return 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
}; };
static TestMemleakInFunction testMemleakInFunction; static TestMemleakInFunction testMemleakInFunction;

View File

@ -1589,7 +1589,7 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
// goto.. // goto/setjmp/longjmp..
checkUninitVar("void foo(int x)\n" checkUninitVar("void foo(int x)\n"
"{\n" "{\n"
" long b;\n" " long b;\n"
@ -1605,6 +1605,18 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("int foo()\n"
"{\n"
" jmp_buf env;\n"
" int a;\n"
" int val = setjmp(env);\n"
" if(val)\n"
" return a;\n"
" a = 1;\n"
" longjmp(env, 1);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// macro_for.. // macro_for..
checkUninitVar("int foo()\n" checkUninitVar("int foo()\n"
"{\n" "{\n"