Fix memleak FP with return with parenthesis (#2202)
* Fix memleak FP with return with parenthesis Fix FPs pointed out by daca@home on the following form: void* f(void) { void* x = malloc(1); return(x); } Fix it by only skipping tokens if there is an actual match with a variable. This allows to remove the special casing of "return;". * Add testcase with cast
This commit is contained in:
parent
6e17853ea9
commit
df800e35d4
|
@ -930,21 +930,21 @@ void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
|||
if (var) {
|
||||
bool used = false;
|
||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ";" || Token::simpleMatch(tok2, "return ;"))
|
||||
if (tok2->str() == ";")
|
||||
break;
|
||||
if (!Token::Match(tok2, "return|(|{|,"))
|
||||
continue;
|
||||
|
||||
tok2 = tok2->next();
|
||||
while (tok2 && tok2->isCast() && tok2->valueType() &&
|
||||
(tok2->valueType()->pointer ||
|
||||
(tok2->valueType()->typeSize(*mSettings) == 0) ||
|
||||
(tok2->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
||||
tok2 = tok2->astOperand2() ? tok2->astOperand2() : tok2->astOperand1();
|
||||
if (Token::Match(tok2, "%varid%", varid))
|
||||
tok2 = tok2->next();
|
||||
else if (Token::Match(tok2, "& %varid% . %name%", varid))
|
||||
tok2 = tok2->tokAt(4);
|
||||
const Token* tok3 = tok2->next();
|
||||
while (tok3 && tok3->isCast() && tok3->valueType() &&
|
||||
(tok3->valueType()->pointer ||
|
||||
(tok3->valueType()->typeSize(*mSettings) == 0) ||
|
||||
(tok3->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
||||
tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
|
||||
if (Token::Match(tok3, "%varid%", varid))
|
||||
tok2 = tok3->next();
|
||||
else if (Token::Match(tok3, "& %varid% . %name%", varid))
|
||||
tok2 = tok3->tokAt(4);
|
||||
else
|
||||
continue;
|
||||
if (Token::Match(tok2, "[});,]")) {
|
||||
|
|
|
@ -154,6 +154,7 @@ private:
|
|||
TEST_CASE(return5);
|
||||
TEST_CASE(return6); // #8282 return {p, p}
|
||||
TEST_CASE(return7); // #9343 return (uint8_t*)x
|
||||
TEST_CASE(return8);
|
||||
|
||||
// General tests: variable type, allocation type, etc
|
||||
TEST_CASE(test1);
|
||||
|
@ -1758,6 +1759,32 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
|
||||
}
|
||||
|
||||
void return8() {
|
||||
check("void* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (x);\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return ((x));\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return ((((x))));\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("char* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (char*)(x);\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void test1() { // 3809
|
||||
check("void f(double*&p) {\n"
|
||||
" p = malloc(0x100);\n"
|
||||
|
|
Loading…
Reference in New Issue