From a19142a6364a7e0b8d20a9fa652700674ff1919a Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Nov 2023 15:04:50 +0100 Subject: [PATCH] Don't report checkLibraryUseIgnore for known functions (refs #7719) --- lib/checkleakautovar.cpp | 18 ++++++++++-------- lib/checkleakautovar.h | 8 ++++---- test/testleakautovar.cpp | 10 ++++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 0f562d65b95..735fa2829a3 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -106,7 +106,7 @@ void VarInfo::print() std::string strusage; const auto use = possibleUsage.find(it->first); if (use != possibleUsage.end()) - strusage = use->second.first; + strusage = use->second.first->str(); std::string status; switch (it->second.status) { @@ -140,7 +140,7 @@ void VarInfo::print() } } -void VarInfo::possibleUsageAll(const std::pair& functionUsage) +void VarInfo::possibleUsageAll(const std::pair& functionUsage) { possibleUsage.clear(); for (std::map::const_iterator it = alloctype.cbegin(); it != alloctype.cend(); ++it) @@ -176,13 +176,15 @@ void CheckLeakAutoVar::deallocReturnError(const Token *tok, const Token *dealloc reportError(locations, Severity::error, "deallocret", "$symbol:" + varname + "\nReturning/dereferencing '$symbol' after it is deallocated / released", CWE672, Certainty::normal); } -void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::pair& functionUsage) +void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::pair& functionUsage) { - if (mSettings->checkLibrary && functionUsage.second == VarInfo::USED) { + if (mSettings->checkLibrary && functionUsage.second == VarInfo::USED && + (!functionUsage.first || !functionUsage.first->function() || !functionUsage.first->function()->hasBody())) { + const std::string funcStr = functionUsage.first ? mSettings->library.getFunctionName(functionUsage.first) : "f"; reportError(tok, Severity::information, "checkLibraryUseIgnore", - "--check-library: Function " + functionUsage.first + "() should have / configuration"); + "--check-library: Function " + funcStr + "() should have / configuration"); } } @@ -684,7 +686,6 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (allocation.status == VarInfo::NOALLOC && Token::simpleMatch(tok, ") ; }")) { if (ftok->isKeyword()) continue; - const std::string functionName(mSettings->library.getFunctionName(ftok)); bool unknown = false; if (mTokenizer->isScopeNoReturn(tok->tokAt(2), &unknown)) { if (!unknown) @@ -693,9 +694,10 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (ftok->function() && !ftok->function()->isAttributeNoreturn() && !(ftok->function()->functionScope && mTokenizer->isScopeNoReturn(ftok->function()->functionScope->bodyEnd))) // check function scope continue; + const std::string functionName(mSettings->library.getFunctionName(ftok)); if (!mSettings->library.isLeakIgnore(functionName) && !mSettings->library.isUse(functionName)) { const VarInfo::Usage usage = Token::simpleMatch(openingPar, "( )") ? VarInfo::NORET : VarInfo::USED; // TODO: check parameters passed to function - varInfo.possibleUsageAll({ functionName, usage }); + varInfo.possibleUsageAll({ ftok, usage }); } } } @@ -895,7 +897,7 @@ void CheckLeakAutoVar::changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocI if (var != alloctype.end()) { if (allocation.status == VarInfo::NOALLOC) { // possible usage - varInfo.possibleUsage[arg->varId()] = { tok->str(), VarInfo::USED }; + varInfo.possibleUsage[arg->varId()] = { tok, VarInfo::USED }; if (var->second.status == VarInfo::DEALLOC && arg->previous()->str() == "&") varInfo.erase(arg->varId()); } else if (var->second.managed()) { diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index a6b2908afa6..23af88ff11c 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -57,7 +57,7 @@ class CPPCHECKLIB VarInfo { }; enum Usage { USED, NORET }; std::map alloctype; - std::map> possibleUsage; + std::map> possibleUsage; std::set conditionalAlloc; std::set referenced; @@ -93,7 +93,7 @@ class CPPCHECKLIB VarInfo { } /** set possible usage for all variables */ - void possibleUsageAll(const std::pair& functionUsage); + void possibleUsageAll(const std::pair& functionUsage); void print(); }; @@ -159,12 +159,12 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { void doubleFreeError(const Token *tok, const Token *prevFreeTok, const std::string &varname, int type); /** message: user configuration is needed to complete analysis */ - void configurationInfo(const Token* tok, const std::pair& functionUsage); + void configurationInfo(const Token* tok, const std::pair& functionUsage); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { CheckLeakAutoVar c(nullptr, settings, errorLogger); c.deallocReturnError(nullptr, nullptr, "p"); - c.configurationInfo(nullptr, { "f", VarInfo::USED }); // user configuration is needed to complete analysis + c.configurationInfo(nullptr, { nullptr, VarInfo::USED }); // user configuration is needed to complete analysis c.doubleFreeError(nullptr, nullptr, "varname", 0); } diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index a08bc2d649a..a847698ad0d 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -2828,6 +2828,16 @@ class TestLeakAutoVar : public TestFixture { " SomeClass::someMethod(a);\n" "}\n", settingsLeakIgnore); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a\n", errout.str()); + + check("void bar(int* p) {\n" + " if (p)\n" + " free(p);\n" + "}\n" + "void f() {\n" + " int* p = malloc(4);\n" + " bar(p);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } };