From cf52ee098ac68be768203a4ab1c77b768b03fa7e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 2 Sep 2022 07:51:10 +0200 Subject: [PATCH] Fix checkLibraryFunction FPs (#4423) * Fix checkLibraryFunction FPs * Fix FP with fclose() * Format * Fix FP with reinterpret_cast --- lib/checkfunctions.cpp | 6 ++++++ lib/checkleakautovar.cpp | 14 ++++++++++---- test/testfunctions.cpp | 9 +++++++++ test/testleakautovar.cpp | 18 ++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index d9321a7c7..56476a442 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -621,6 +621,9 @@ void CheckFunctions::checkLibraryMatchFunctions() if (tok->function()) continue; + if (Token::simpleMatch(tok->astTop(), "throw")) + continue; + if (!mSettings->library.isNotLibraryFunction(tok)) continue; @@ -631,6 +634,9 @@ void CheckFunctions::checkLibraryMatchFunctions() if (mSettings->library.functions.find(functionName) != mSettings->library.functions.end()) continue; + if (mSettings->library.podtype(tok->expressionString())) + continue; + const Token* start = tok; while (Token::Match(start->tokAt(-2), "%name% ::")) start = start->tokAt(-2); diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index a9c0bb14a..06efba232 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -777,7 +777,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t rhs = rhs->astParent(); } while (rhs->isCast()) { - rhs = rhs->astOperand1(); + rhs = rhs->astOperand2() ? rhs->astOperand2() : rhs->astOperand1(); } if (rhs->varId() == tok->varId()) { // simple assignment @@ -814,7 +814,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t if (returnValue.compare(0, 3, "arg") == 0) // the function returns one of its argument, we need to process a potential assignment return openingPar; - return openingPar->link(); + return isCPPCast(tok->astParent()) ? openingPar : openingPar->link(); } return nullptr; @@ -917,8 +917,14 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin const bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0; // Is variable allocated? - if (!isnull && (!af || af->arg == argNr)) - changeAllocStatus(varInfo, allocation, tokName, arg); + if (!isnull && (!af || af->arg == argNr)) { + const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName); + VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); + if (dealloc.type == 0) + changeAllocStatus(varInfo, allocation, tokName, arg); + else + changeAllocStatus(varInfo, dealloc, tokName, arg); + } } // Check smart pointer else if (Token::Match(arg, "%name% < %type%") && mSettings->library.isSmartPointer(argTypeStartTok)) { diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 22599425b..a59062712 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1831,9 +1831,18 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + check("void f(std::uint64_t& u) {\n" + " u = std::uint32_t(u) * std::uint64_t(100);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + check("void f() { throw(1); }\n"); // #8958 ASSERT_EQUALS("", errout.str()); + check("using namespace std;\n" + "void f() { throw range_error(\"abc\"); }\n"); + ASSERT_EQUALS("", errout.str()); + check("class C {\n" // #9002 "public:\n" " static int f() { return 1; }\n" diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 1a3c68211..6703a6a1c 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -2432,6 +2432,24 @@ private: " asm goto(\"assembler code\");\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " FILE* p = fopen(\"abc.txt\", \"r\");\n" + " if (fclose(p) != 0) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct S;\n" + "void f(int a, int b, S*& p) {\n" + " if (a == -1) {\n" + " FILE* file = fopen(\"abc.txt\", \"r\");\n" + " }\n" + " if (b) {\n" + " void* buf = malloc(10);\n" + " p = reinterpret_cast(buf);\n" + " }\n" + "}\n", /*cpp*/ true); + ASSERT_EQUALS("[test.cpp:5]: (error) Resource leak: file\n", errout.str()); } void ptrptr() {