Fix #4400 FN (error) Memory leak - assignment to reference of a pointer (#5048)

* Fix #4400 false negative: (error) Memory leak - assignment to reference of a pointer

* Comment

* Run tests as C++

* Add TODOs

* Bail out for local references
This commit is contained in:
chrchr-github 2023-05-23 06:29:20 +02:00 committed by GitHub
parent 9e8cb6904a
commit 6d2662b8a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 4 deletions

View File

@ -246,7 +246,7 @@ static bool isLocalVarNoAutoDealloc(const Token *varTok, const bool isCpp)
return false; return false;
// Don't check reference variables // Don't check reference variables
if (var->isReference()) if (var->isReference() && !var->isArgument())
return false; return false;
// non-pod variable // non-pod variable
@ -1077,7 +1077,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
if (used && it->second.status == VarInfo::DEALLOC) if (used && it->second.status == VarInfo::DEALLOC)
deallocReturnError(tok, it->second.allocTok, var->name()); deallocReturnError(tok, it->second.allocTok, var->name());
else if (!used && !it->second.managed()) { else if (!used && !it->second.managed() && !var->isReference()) {
const auto use = possibleUsage.find(varid); const auto use = possibleUsage.find(varid);
if (use == possibleUsage.end()) { if (use == possibleUsage.end()) {
leakError(tok, var->name(), it->second.type); leakError(tok, var->name(), it->second.type);

View File

@ -2324,11 +2324,32 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void test1() { // 3809 void test1() {
check("void f(double*&p) {\n" check("void f(double*&p) {\n" // 3809
" p = malloc(0x100);\n" " p = malloc(0x100);\n"
"}", /*cpp*/ true); "}", /*cpp*/ true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int*& p) {\n" // #4400
" p = (int*)malloc(4);\n"
" p = (int*)malloc(4);\n"
"}\n", /*cpp*/ true);
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: p\n", errout.str());
check("void f() {\n"
" int* p = (int*)malloc(4);\n"
" int*& r = p;\n"
" r = (int*)malloc(4);\n"
"}\n", /*cpp*/ true);
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", "", errout.str());
check("void f() {\n"
" int* p = (int*)malloc(4);\n"
" int*& r = p;\n"
" free(r);\n"
" p = (int*)malloc(4);\n"
"}\n", /*cpp*/ true);
TODO_ASSERT_EQUALS("", "[test.cpp:6]: (error) Memory leak: p\n", errout.str());
} }
void test2() { // 3899 void test2() { // 3899