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;
|
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
|
bool CheckMemoryLeakInFunction::matchFunctionsThatReturnArg(const Token *tok, unsigned int varid) const
|
||||||
{
|
{
|
||||||
return Token::Match(tok, "; %varid% = strcat|memcpy|memmove|strcpy ( %varid% ,", varid);
|
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))
|
sizeof(call_func_white_list[0]), call_func_white_list_compare))
|
||||||
return 0;
|
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))
|
if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1891,6 +1933,9 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
|||||||
|
|
||||||
void CheckMemoryLeakInFunction::check()
|
void CheckMemoryLeakInFunction::check()
|
||||||
{
|
{
|
||||||
|
// Parse the tokens and fill the "noreturn"
|
||||||
|
parse_noreturn();
|
||||||
|
|
||||||
bool classmember = false;
|
bool classmember = false;
|
||||||
bool beforeParameters = false;
|
bool beforeParameters = false;
|
||||||
bool infunc = false;
|
bool infunc = false;
|
||||||
|
@ -165,6 +165,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool matchFunctionsThatReturnArg(const Token *tok, unsigned int varid) const;
|
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";
|
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(exit2);
|
||||||
TEST_CASE(exit4);
|
TEST_CASE(exit4);
|
||||||
TEST_CASE(exit5);
|
TEST_CASE(exit5);
|
||||||
|
TEST_CASE(noreturn);
|
||||||
TEST_CASE(stdstring);
|
TEST_CASE(stdstring);
|
||||||
|
|
||||||
TEST_CASE(strndup_function);
|
TEST_CASE(strndup_function);
|
||||||
@ -2071,6 +2072,19 @@ private:
|
|||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void stdstring()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user