Merge pull request #2802 from rikardfalkeborn/9228-fix-fn-with-realloc-and-null-assignment

Improve memleakOnRealloc with assignment to NULL
This commit is contained in:
Daniel Marjamäki 2020-09-14 11:04:29 +02:00 committed by GitHub
commit 4dd85cfbe0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 3 deletions

View File

@ -547,9 +547,14 @@ void CheckMemoryLeakInFunction::checkReallocUsage()
// Check that another copy of the pointer wasn't saved earlier in the function
if (Token::findmatch(scope->bodyStart, "%name% = %varid% ;", tok, tok->varId()) ||
Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %name% .| %name%| [;=]", tok, tok->varId()))
Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %var% .| %var%| [;=]", tok, tok->varId()))
continue;
// Check if the argument is known to be null, which means it is not a memory leak
if (arg->hasKnownIntValue() && arg->getKnownIntValue() == 0) {
continue;
}
const Token* tokEndRealloc = reallocTok->linkAt(1);
// Check that the allocation isn't followed immediately by an 'if (!var) { error(); }' that might handle failure
if (Token::simpleMatch(tokEndRealloc->next(), "; if (") &&

View File

@ -169,6 +169,7 @@ private:
TEST_CASE(realloc21);
TEST_CASE(realloc22);
TEST_CASE(realloc23);
TEST_CASE(realloc24); // #9228
TEST_CASE(reallocarray1);
}
@ -201,7 +202,7 @@ private:
" free(a);\n"
"}");
TODO_ASSERT_EQUALS("", "[test.cpp:4]: (error) Common realloc mistake: 'a' nulled but not freed upon failure\n", errout.str());
ASSERT_EQUALS("", errout.str());
}
void realloc4() {
@ -296,7 +297,7 @@ private:
" return;\n"
" free(a);\n"
"}");
TODO_ASSERT_EQUALS("", "[test.cpp:4]: (error) Common realloc mistake: 'a' nulled but not freed upon failure\n", errout.str());
ASSERT_EQUALS("", errout.str());
}
void realloc13() {
@ -410,6 +411,35 @@ private:
ASSERT_EQUALS("", errout.str());
}
void realloc24() { // #9228
check("void f() {\n"
"void *a = NULL;\n"
"a = realloc(a, 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
"void *a = NULL;\n"
"a = malloc(10);\n"
"a = realloc(a, 20);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str());
check("void f() {\n"
"void *a = std::nullptr;\n"
"a = malloc(10);\n"
"a = realloc(a, 20);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str());
check("void f(char *b) {\n"
"void *a = NULL;\n"
"a = b;\n"
"a = realloc(a, 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void reallocarray1() {
check("void foo()\n"
"{\n"