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) {
|
if (var) {
|
||||||
bool used = false;
|
bool used = false;
|
||||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == ";" || Token::simpleMatch(tok2, "return ;"))
|
if (tok2->str() == ";")
|
||||||
break;
|
break;
|
||||||
if (!Token::Match(tok2, "return|(|{|,"))
|
if (!Token::Match(tok2, "return|(|{|,"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tok2 = tok2->next();
|
const Token* tok3 = tok2->next();
|
||||||
while (tok2 && tok2->isCast() && tok2->valueType() &&
|
while (tok3 && tok3->isCast() && tok3->valueType() &&
|
||||||
(tok2->valueType()->pointer ||
|
(tok3->valueType()->pointer ||
|
||||||
(tok2->valueType()->typeSize(*mSettings) == 0) ||
|
(tok3->valueType()->typeSize(*mSettings) == 0) ||
|
||||||
(tok2->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
(tok3->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
||||||
tok2 = tok2->astOperand2() ? tok2->astOperand2() : tok2->astOperand1();
|
tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
|
||||||
if (Token::Match(tok2, "%varid%", varid))
|
if (Token::Match(tok3, "%varid%", varid))
|
||||||
tok2 = tok2->next();
|
tok2 = tok3->next();
|
||||||
else if (Token::Match(tok2, "& %varid% . %name%", varid))
|
else if (Token::Match(tok3, "& %varid% . %name%", varid))
|
||||||
tok2 = tok2->tokAt(4);
|
tok2 = tok3->tokAt(4);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok2, "[});,]")) {
|
if (Token::Match(tok2, "[});,]")) {
|
||||||
|
|
|
@ -154,6 +154,7 @@ private:
|
||||||
TEST_CASE(return5);
|
TEST_CASE(return5);
|
||||||
TEST_CASE(return6); // #8282 return {p, p}
|
TEST_CASE(return6); // #8282 return {p, p}
|
||||||
TEST_CASE(return7); // #9343 return (uint8_t*)x
|
TEST_CASE(return7); // #9343 return (uint8_t*)x
|
||||||
|
TEST_CASE(return8);
|
||||||
|
|
||||||
// General tests: variable type, allocation type, etc
|
// General tests: variable type, allocation type, etc
|
||||||
TEST_CASE(test1);
|
TEST_CASE(test1);
|
||||||
|
@ -1758,6 +1759,32 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
|
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
|
void test1() { // 3809
|
||||||
check("void f(double*&p) {\n"
|
check("void f(double*&p) {\n"
|
||||||
" p = malloc(0x100);\n"
|
" p = malloc(0x100);\n"
|
||||||
|
|
Loading…
Reference in New Issue