Avoid some additional memleakOnRealloc false positives (#2422)

* Avoid some additional memleakOnRealloc false positives

checkReallocUsage() already contains code to suppress the
`p = realloc(p, size)` error message when the pointer has been
previously copied from another variable (hence there is an additional
copy of the original pointer value) within the same function, as in
the added realloc21() test case.

Extend this so that `p = *pp` and `p = ptr->foo` are also recognized
as copies from another variable with the same original pointer value,
as in the added realloc22() and realloc23() test cases.

* Rewrite as a single findmatch() expression
This commit is contained in:
John Marshall 2019-12-04 11:13:44 +00:00 committed by Daniel Marjamäki
parent fb96e5433a
commit 297efcd049
2 changed files with 37 additions and 1 deletions

View File

@ -551,7 +551,7 @@ 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% [;=]", tok, tok->varId()))
Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %name% .| %name%| [;=]", tok, tok->varId()))
continue;
const Token* tokEndRealloc = reallocTok->linkAt(1);

View File

@ -172,6 +172,9 @@ private:
TEST_CASE(realloc18);
TEST_CASE(realloc19);
TEST_CASE(realloc20);
TEST_CASE(realloc21);
TEST_CASE(realloc22);
TEST_CASE(realloc23);
TEST_CASE(reallocarray1);
}
@ -380,6 +383,39 @@ private:
ASSERT_EQUALS("", errout.str());
}
void realloc21() {
check("char *foo(char *bs0)\n"
"{\n"
" char *bs = bs0;\n"
" bs = realloc(bs, 100);\n"
" if (bs == NULL) return bs0;\n"
" return bs;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void realloc22() {
check("void foo(char **bsp)\n"
"{\n"
" char *bs = *bsp;\n"
" bs = realloc(bs, 100);\n"
" if (bs == NULL) return;\n"
" *bsp = bs;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void realloc23() {
check("void foo(struct ABC *s)\n"
"{\n"
" uint32_t *cigar = s->cigar;\n"
" if (!(cigar = realloc(cigar, 100 * sizeof(*cigar))))\n"
" return;\n"
" s->cigar = cigar;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void reallocarray1() {
check("void foo()\n"
"{\n"