CheckLeakAutoVar: better handling of noreturn functions. Partial fix for #7918.

This commit is contained in:
Daniel Marjamäki 2017-02-25 11:36:48 +01:00
parent 3f1e2b4270
commit 99544069d1
2 changed files with 33 additions and 4 deletions

View File

@ -230,6 +230,12 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
while (Token::Match(varTok, "%name% ::|. %name% !!(")) while (Token::Match(varTok, "%name% ::|. %name% !!("))
varTok = varTok->tokAt(2); varTok = varTok->tokAt(2);
const Token *ftok = tok;
if (ftok->str() == "::")
ftok = ftok->next();
while (Token::Match(ftok, "%name% :: %name%"))
ftok = ftok->tokAt(2);
// assignment.. // assignment..
if (Token::Match(varTok, "%var% =")) { if (Token::Match(varTok, "%var% =")) {
// taking address of another variable.. // taking address of another variable..
@ -444,14 +450,14 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
} }
// Function call.. // Function call..
else if (Token::Match(tok, "%type% (")) { else if (Token::Match(ftok, "%type% (")) {
const Library::AllocFunc* af = _settings->library.dealloc(tok); const Library::AllocFunc* af = _settings->library.dealloc(ftok);
VarInfo::AllocInfo allocation(af ? af->groupId : 0, VarInfo::DEALLOC); VarInfo::AllocInfo allocation(af ? af->groupId : 0, VarInfo::DEALLOC);
if (allocation.type == 0) if (allocation.type == 0)
allocation.status = VarInfo::NOALLOC; allocation.status = VarInfo::NOALLOC;
functionCall(tok, varInfo, allocation, af); functionCall(ftok, varInfo, allocation, af);
tok = tok->next()->link(); tok = ftok->next()->link();
// Handle scopes that might be noreturn // Handle scopes that might be noreturn
if (allocation.status == VarInfo::NOALLOC && Token::simpleMatch(tok, ") ; }")) { if (allocation.status == VarInfo::NOALLOC && Token::simpleMatch(tok, ") ; }")) {

View File

@ -71,6 +71,7 @@ private:
// exit // exit
TEST_CASE(exit1); TEST_CASE(exit1);
TEST_CASE(exit2); TEST_CASE(exit2);
TEST_CASE(exit3);
// goto // goto
TEST_CASE(goto1); TEST_CASE(goto1);
@ -849,6 +850,28 @@ private:
errout.str()); errout.str());
} }
void exit3() {
check("void f() {\n"
" char *p = malloc(100);\n"
" if (x) {\n"
" free(p);\n"
" ::exit(0);\n"
" }"
" free(p);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" char *p = malloc(100);\n"
" if (x) {\n"
" free(p);\n"
" std::exit(0);\n"
" }"
" free(p);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void goto1() { void goto1() {
check("static void f() {\n" check("static void f() {\n"
" int err = -ENOMEM;\n" " int err = -ENOMEM;\n"