Fixed #944 (new false positives against Wine Git Tree)
This commit is contained in:
parent
ec6d66ff45
commit
fee96f3cd6
|
@ -424,6 +424,45 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
|
|||
return No;
|
||||
}
|
||||
|
||||
|
||||
void CheckMemoryLeakInFunction::parse_noreturn()
|
||||
{
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||
{
|
||||
if (tok->str() == "{")
|
||||
tok = tok->link();
|
||||
if (tok->str() == "(")
|
||||
{
|
||||
const std::string function_name((tok->previous() && tok->previous()->isName()) ? tok->strAt(-1) : "");
|
||||
|
||||
tok = tok->link();
|
||||
|
||||
if (!function_name.empty() && Token::simpleMatch(tok, ") {"))
|
||||
{
|
||||
// parse this function to check if it contains an "exit" call..
|
||||
unsigned int indentlevel = 0;
|
||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
|
||||
{
|
||||
if (tok2->str() == "{")
|
||||
++indentlevel;
|
||||
else if (tok2->str() == "}")
|
||||
{
|
||||
if (indentlevel <= 1)
|
||||
break;
|
||||
--indentlevel;
|
||||
}
|
||||
if (Token::Match(tok2, "[;{}] exit ("))
|
||||
{
|
||||
noreturn.insert(function_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CheckMemoryLeakInFunction::matchFunctionsThatReturnArg(const Token *tok, unsigned int varid) const
|
||||
{
|
||||
return Token::Match(tok, "; %varid% = strcat|memcpy|memmove|strcpy ( %varid% ,", varid);
|
||||
|
@ -473,6 +512,9 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
|
|||
sizeof(call_func_white_list[0]), call_func_white_list_compare))
|
||||
return 0;
|
||||
|
||||
if (noreturn.find(tok->str()) != noreturn.end())
|
||||
return "exit";
|
||||
|
||||
if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
|
||||
return 0;
|
||||
|
||||
|
@ -1891,6 +1933,9 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
|||
|
||||
void CheckMemoryLeakInFunction::check()
|
||||
{
|
||||
// Parse the tokens and fill the "noreturn"
|
||||
parse_noreturn();
|
||||
|
||||
bool classmember = false;
|
||||
bool beforeParameters = false;
|
||||
bool infunc = false;
|
||||
|
|
|
@ -165,6 +165,7 @@ public:
|
|||
private:
|
||||
#endif
|
||||
|
||||
|
||||
bool matchFunctionsThatReturnArg(const Token *tok, unsigned int varid) const;
|
||||
|
||||
/**
|
||||
|
@ -271,6 +272,9 @@ private:
|
|||
{
|
||||
return "Is there any allocated memory when a function goes out of scope";
|
||||
}
|
||||
|
||||
void parse_noreturn();
|
||||
std::set<std::string> noreturn;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -247,6 +247,7 @@ private:
|
|||
TEST_CASE(exit2);
|
||||
TEST_CASE(exit4);
|
||||
TEST_CASE(exit5);
|
||||
TEST_CASE(noreturn);
|
||||
TEST_CASE(stdstring);
|
||||
|
||||
TEST_CASE(strndup_function);
|
||||
|
@ -2071,6 +2072,19 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void noreturn()
|
||||
{
|
||||
check("void fatal_error()\n"
|
||||
"{ exit(1); }\n"
|
||||
"\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" char *p = malloc(100);\n"
|
||||
" fatal_error();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void stdstring()
|
||||
|
|
Loading…
Reference in New Issue