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:
Rikard Falkeborn 2019-09-22 19:18:31 +02:00 committed by Daniel Marjamäki
parent 6e17853ea9
commit df800e35d4
2 changed files with 38 additions and 11 deletions

View File

@ -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, "[});,]")) {

View File

@ -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"