From 1eee68f039a21b18f023b0aab50856355e9a5148 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 4 Jan 2024 22:10:24 +0100 Subject: [PATCH] Fix FN deallocuse with function call (refs #11409) (#5822) --- lib/checkleakautovar.cpp | 8 ++++++-- test/testleakautovar.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 138916c11c3..14b9b47eb8e 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -1045,7 +1045,11 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin const VarInfo::AllocInfo sp_allocation(sp_af ? sp_af->groupId : (arrayDelete ? NEW_ARRAY : NEW), VarInfo::OWNED, allocTok); changeAllocStatus(varInfo, sp_allocation, vtok, vtok); } else { - checkTokenInsideExpression(arg, varInfo, /*inFuncCall*/ isLeakIgnore); + const Token* const nextArg = funcArg->nextArgument(); + do { + checkTokenInsideExpression(arg, varInfo, /*inFuncCall*/ isLeakIgnore); + arg = arg->next(); + } while ((nextArg && arg != nextArg) || (!nextArg && arg != tokOpeningPar->link())); } // TODO: check each token in argument expression (could contain multiple variables) argNr++; @@ -1111,7 +1115,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == ";") break; - if (!Token::Match(tok2, "return|(|{|,")) + if (!Token::Match(tok2, "return|(|{|,|*")) continue; const Token* tok3 = tok2->next(); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index ad2212ff298..280c428345c 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -942,6 +942,45 @@ class TestLeakAutoVar : public TestFixture { "}\n"); ASSERT_EQUALS("[test.c:4]: (error) Dereferencing 'p' after it is deallocated / released\n", errout.str()); + + check("int g(int);\n" + "void f(int* p) {\n" + " free(p);\n" + " g(*p);\n" + "}\n" + "int h(int* p) {\n" + " free(p);\n" + " return g(*p);\n" + "}\n"); + ASSERT_EQUALS("[test.c:4]: (error) Dereferencing 'p' after it is deallocated / released\n" + "[test.c:7] -> [test.c:8]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", + errout.str()); + + check("int g(int);\n" + "void f(int* p) {\n" + " free(p);\n" + " g(1 + *p);\n" + "}\n" + "int h(int* p) {\n" + " free(p);\n" + " return g(1 + *p);\n" + "}\n"); + ASSERT_EQUALS("[test.c:4]: (error) Dereferencing 'p' after it is deallocated / released\n" + "[test.c:7] -> [test.c:8]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", + errout.str()); + + check("int g(int, int);\n" + "void f(int* p) {\n" + " free(p);\n" + " g(0, 1 + *p);\n" + "}\n" + "int h(int* p) {\n" + " free(p);\n" + " return g(0, 1 + *p);\n" + "}\n"); + ASSERT_EQUALS("[test.c:4]: (error) Dereferencing 'p' after it is deallocated / released\n" + "[test.c:7] -> [test.c:8]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", + errout.str()); } void doublefree1() { // #3895