diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index e402d726f..0efd37f12 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -499,7 +499,8 @@ void CheckClass::copyconstructors() } } for (tok = func.functionScope->bodyStart; tok != func.functionScope->bodyEnd; tok = tok->next()) { - if (Token::Match(tok, "%var% = new|malloc|g_malloc|g_try_malloc|realloc|g_realloc|g_try_realloc")) { + if ((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + (Token::Match(tok, "%var% = %name% (") && (mSettings->library.getAllocFuncInfo(tok->tokAt(2)) || mSettings->library.getReallocFuncInfo(tok->tokAt(2))))) { allocatedVars.erase(tok->varId()); } else if (Token::Match(tok, "%var% = %name% . %name% ;") && allocatedVars.find(tok->varId()) != allocatedVars.end()) { copiedVars.insert(tok); @@ -1404,7 +1405,8 @@ void CheckClass::checkMemset() const std::set parsedTypes; checkMemsetType(scope, tok, type, false, parsedTypes); } - } else if (tok->variable() && tok->variable()->typeScope() && Token::Match(tok, "%var% = calloc|malloc|realloc|g_malloc|g_try_malloc|g_realloc|g_try_realloc (")) { + } else if (tok->variable() && tok->variable()->typeScope() && Token::Match(tok, "%var% = %name% (") && + (mSettings->library.getAllocFuncInfo(tok->tokAt(2)) || mSettings->library.getReallocFuncInfo(tok->tokAt(2)))) { const std::set parsedTypes; checkMemsetType(scope, tok->tokAt(2), tok->variable()->typeScope(), true, parsedTypes); @@ -1737,16 +1739,18 @@ bool CheckClass::hasAllocation(const Function *func, const Scope* scope, const T if (!end) end = func->functionScope->bodyEnd; for (const Token *tok = start; tok && (tok != end); tok = tok->next()) { - if (Token::Match(tok, "%var% = malloc|realloc|calloc|new") && isMemberVar(scope, tok)) + if (((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) && + isMemberVar(scope, tok)) return true; // check for deallocating memory const Token *var; if (Token::Match(tok, "%name% ( %var%") && mSettings->library.getDeallocFuncInfo(tok)) var = tok->tokAt(2); - else if (Token::Match(tok, "delete [ ] %var%")) + else if (mTokenizer->isCPP() && Token::Match(tok, "delete [ ] %var%")) var = tok->tokAt(3); - else if (Token::Match(tok, "delete %var%")) + else if (mTokenizer->isCPP() && Token::Match(tok, "delete %var%")) var = tok->next(); else continue; diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index bb9e8f78f..06d7b779f 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -693,7 +693,7 @@ void CheckMemoryLeakStructMember::check() const } } -bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) +bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const { if (!variable) return false; @@ -702,7 +702,7 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) { if (Token::Match(tok2, "= %varid% [;=]", declarationId)) return false; - if (Token::Match(tok2, "%varid% = malloc|kmalloc (", declarationId)) // TODO use library + if (Token::Match(tok2, "%varid% = %name% (", declarationId) && mSettings->library.getAllocFuncInfo(tok2->tokAt(2))) alloc = true; } return alloc; diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index b38336810..48144668f 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -279,7 +279,7 @@ public: private: /** Is local variable allocated with malloc? */ - static bool isMalloc(const Variable *variable); + bool isMalloc(const Variable *variable) const; void checkStructVariable(const Variable* const variable) const; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 121ae89b7..2a167a068 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2310,7 +2310,8 @@ void CheckOther::checkInvalidFree() for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { // Keep track of which variables were assigned addresses to newly-allocated memory - if (Token::Match(tok, "%var% = malloc|g_malloc|new")) { + if ((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) { allocation.insert(std::make_pair(tok->varId(), tok->strAt(2))); inconclusive.insert(std::make_pair(tok->varId(), false)); } diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 0d1b8916e..220195401 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -127,12 +127,12 @@ void CheckSizeof::checkSizeofForPointerSize() // Once leaving those tests, it is mandatory to have: // - variable matching the used pointer // - tokVar pointing on the argument where sizeof may be used - if (Token::Match(tok->tokAt(2), "malloc|alloca|calloc (")) { + if (Token::Match(tok->tokAt(2), "%name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2))) { if (Token::Match(tok, "%var% =")) variable = tok; else if (tok->strAt(1) == ")" && Token::Match(tok->linkAt(1)->tokAt(-2), "%var% =")) variable = tok->linkAt(1)->tokAt(-2); - else if (tok->link() && Token::Match(tok, "> ( malloc|alloca|calloc (") && Token::Match(tok->link()->tokAt(-3), "%var% =")) + else if (tok->link() && Token::Match(tok, "> ( %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)) && Token::Match(tok->link()->tokAt(-3), "%var% =")) variable = tok->link()->tokAt(-3); tokSize = tok->tokAt(4); tokFunc = tok->tokAt(2); diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index d427d730c..ed4fd69a3 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1028,7 +1028,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const if (var) { // Consider allocating memory separately because allocating/freeing alone does not constitute using the variable if (var->mType == Variables::pointer && - Token::Match(skipBrackets(tok->next()), "= new|malloc|calloc|kmalloc|kzalloc|kcalloc|strdup|strndup|vmalloc|g_new0|g_try_new|g_new|g_malloc|g_malloc0|g_try_malloc|g_try_malloc0|g_strdup|g_strndup|g_strdup_printf")) { + ((mTokenizer->isCPP() && Token::simpleMatch(skipBrackets(tok->next()), "= new")) || + (Token::Match(skipBrackets(tok->next()), "= %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2))))) { variables.allocateMemory(varid, tok); } else if (var->mType == Variables::pointer || var->mType == Variables::reference) { variables.read(varid, tok); diff --git a/test/testclass.cpp b/test/testclass.cpp index c9ddee6b2..9ed7823ba 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -2891,7 +2891,7 @@ private: #define checkNoMemset(...) checkNoMemset_(__FILE__, __LINE__, __VA_ARGS__) void checkNoMemset_(const char* file, int line, const char code[]) { - const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).build(); + const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).library("std.cfg").build(); checkNoMemset_(file, line, code, settings); } diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index bcf04a5db..fafc84526 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -36,7 +36,7 @@ public: TestSizeof() : TestFixture("TestSizeof") {} private: - const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).certainty(Certainty::inconclusive).build(); + const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).certainty(Certainty::inconclusive).library("std.cfg").build(); void run() override { TEST_CASE(sizeofsizeof);