From d81a758850b98c7b7114e6ed89e5245ed4a52b15 Mon Sep 17 00:00:00 2001 From: PKEuS <731902+PKEuS@users.noreply.github.com> Date: Sun, 21 Aug 2022 17:21:02 +0200 Subject: [PATCH] LCppC backports: Refactorizations/Optimizations (#4204) --- lib/astutils.cpp | 29 +++++++++++++++-------------- lib/checkmemoryleak.cpp | 18 ++++++------------ lib/checkuninitvar.cpp | 12 ++++++------ lib/checkvaarg.cpp | 4 +--- lib/clangimport.cpp | 1 + lib/clangimport.h | 4 +++- lib/cppcheck.vcxproj | 8 ++++++++ lib/cppcheck.vcxproj.filters | 26 +++++++++++++++++++++++++- lib/symboldatabase.cpp | 8 ++------ lib/symboldatabase.h | 4 ++-- test/testrunner.vcxproj | 1 + test/testrunner.vcxproj.filters | 5 ++++- 12 files changed, 74 insertions(+), 46 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index e30798d45..42c816fda 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1865,21 +1865,22 @@ bool isUniqueExpression(const Token* tok) const Type * varType = var->type(); // Iterate over the variables in scope and the parameters of the function if possible const Function * fun = scope->function; - const std::list* setOfVars[] = {&scope->varlist, fun ? &fun->argumentList : nullptr}; - for (const std::list* vars:setOfVars) { - if (!vars) - continue; - bool other = std::any_of(vars->cbegin(), vars->cend(), [=](const Variable &v) { - if (varType) - return v.type() && v.type()->name() == varType->name() && v.name() != var->name(); - return v.isFloatingType() == var->isFloatingType() && - v.isEnumType() == var->isEnumType() && - v.isClass() == var->isClass() && - v.isArray() == var->isArray() && - v.isPointer() == var->isPointer() && - v.name() != var->name(); - }); + auto pred = [=](const Variable& v) { + if (varType) + return v.type() && v.type()->name() == varType->name() && v.name() != var->name(); + return v.isFloatingType() == var->isFloatingType() && + v.isEnumType() == var->isEnumType() && + v.isClass() == var->isClass() && + v.isArray() == var->isArray() && + v.isPointer() == var->isPointer() && + v.name() != var->name(); + }; + bool other = std::any_of(scope->varlist.cbegin(), scope->varlist.cend(), pred); + if (other) + return false; + if (fun) { + other = std::any_of(fun->argumentList.cbegin(), fun->argumentList.cend(), pred); if (other) return false; } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 0affa7723..7c0013abe 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -354,7 +354,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Function* f return No; // Get return pointer.. - int varid = 0; + const Variable* var = nullptr; for (const Token *tok2 = func->functionScope->bodyStart; tok2 != func->functionScope->bodyEnd; tok2 = tok2->next()) { if (const Token *endOfLambda = findLambdaEndToken(tok2)) tok2 = endOfLambda; @@ -371,24 +371,24 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Function* f if (Token::Match(tok, ".|::")) tok = tok->astOperand2() ? tok->astOperand2() : tok->astOperand1(); if (tok) - varid = tok->varId(); + var = tok->variable(); break; } } // Not returning pointer value.. - if (varid == 0) + if (!var) return No; // If variable is not local then alloctype shall be "No" // Todo: there can be false negatives about mismatching allocation/deallocation. // => Generate "alloc ; use ;" if variable is not local? - const Variable *var = mTokenizer_->getSymbolDatabase()->getVariableFromVarId(varid); - if (!var || !var->isLocal() || var->isStatic()) + if (!var->isLocal() || var->isStatic()) return No; // Check if return pointer is allocated.. AllocType allocType = No; + nonneg int varid = var->declarationId(); for (const Token* tok = func->functionScope->bodyStart; tok != func->functionScope->bodyEnd; tok = tok->next()) { if (Token::Match(tok, "%varid% =", varid)) { allocType = getAllocationType(tok->tokAt(2), varid, callstack); @@ -452,12 +452,6 @@ bool CheckMemoryLeakInFunction::test_white_list(const std::string &funcname, con // a = malloc(10); a = realloc(a, 100); //--------------------------------------------------------------------------- -static bool isNoArgument(const SymbolDatabase* symbolDatabase, nonneg int varid) -{ - const Variable* var = symbolDatabase->getVariableFromVarId(varid); - return var && !var->isArgument(); -} - void CheckMemoryLeakInFunction::checkReallocUsage() { // only check functions @@ -497,7 +491,7 @@ void CheckMemoryLeakInFunction::checkReallocUsage() if (!arg || !tok2) continue; - if (!((tok->varId() == arg->varId()) && isNoArgument(symbolDatabase, tok->varId()))) + if (!(tok->varId() == arg->varId() && tok->variable() && !tok->variable()->isArgument())) continue; // Check that another copy of the pointer wasn't saved earlier in the function diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 8270b2bdd..7dbaecdf2 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -162,8 +162,6 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set continue; if (var.isArray()) { - Alloc alloc = ARRAY; - const std::map variableValue; bool init = false; for (const Token *parent = var.nameToken(); parent; parent = parent->astParent()) { if (parent->str() == "=") { @@ -171,8 +169,11 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set break; } } - if (!init) + if (!init) { + Alloc alloc = ARRAY; + const std::map variableValue; checkScopeForVariable(tok, var, nullptr, nullptr, &alloc, emptyString, variableValue); + } continue; } if (stdtype || var.isPointer()) { @@ -444,8 +445,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var const Token *condVarTok = nullptr; if (alwaysFalse) ; - else if (Token::simpleMatch(tok, "if (") && - astIsVariableComparison(tok->next()->astOperand2(), "!=", "0", &condVarTok)) { + else if (astIsVariableComparison(tok->next()->astOperand2(), "!=", "0", &condVarTok)) { const std::map::const_iterator it = variableValue.find(condVarTok->varId()); if (it != variableValue.end() && it->second != 0) return true; // this scope is not fully analysed => return true @@ -453,7 +453,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var condVarId = condVarTok->varId(); condVarValue = !VariableValue(0); } - } else if (Token::simpleMatch(tok, "if (") && Token::Match(tok->next()->astOperand2(), "==|!=")) { + } else if (Token::Match(tok->next()->astOperand2(), "==|!=")) { const Token *condition = tok->next()->astOperand2(); const Token *lhs = condition->astOperand1(); const Token *rhs = condition->astOperand2(); diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 2ee75cf4e..2a2381488 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -68,9 +68,7 @@ void CheckVaarg::va_start_argument() if (var && var->isReference()) referenceAs_va_start_error(param2, var->name()); if (var && var->index() + 2 < function->argCount() && printWarnings) { - std::list::const_reverse_iterator it = function->argumentList.rbegin(); - ++it; - wrongParameterTo_va_start_error(tok, var->name(), it->name()); + wrongParameterTo_va_start_error(tok, var->name(), function->argumentList[function->argumentList.size()-2].name()); } tok = tok->linkAt(1); } diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index e5977b4c4..364d2f82a 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -1371,6 +1371,7 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList) function->nestedIn = nestedIn; function->argDef = par1; // Function arguments + function->argumentList.reserve(children.size()); for (int i = 0; i < children.size(); ++i) { AstNodePtr child = children[i]; if (child->nodeType != ParmVarDecl) diff --git a/lib/clangimport.h b/lib/clangimport.h index cb7a5541c..5aabe25fa 100644 --- a/lib/clangimport.h +++ b/lib/clangimport.h @@ -22,12 +22,14 @@ #define clangimportH //--------------------------------------------------------------------------- +#include "config.h" + #include class Tokenizer; namespace clangimport { - void parseClangAstDump(Tokenizer *tokenizer, std::istream &f); + void CPPCHECKLIB parseClangAstDump(Tokenizer *tokenizer, std::istream &f); } #endif diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 28cc5b3ed..8f77ee9bb 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -106,8 +106,10 @@ + + @@ -141,17 +143,22 @@ + + + + + @@ -163,6 +170,7 @@ + diff --git a/lib/cppcheck.vcxproj.filters b/lib/cppcheck.vcxproj.filters index 5595bd5ae..e3f777b75 100644 --- a/lib/cppcheck.vcxproj.filters +++ b/lib/cppcheck.vcxproj.filters @@ -370,6 +370,30 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -377,4 +401,4 @@ - + \ No newline at end of file diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e1a34fbd6..a2e385db5 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4272,12 +4272,8 @@ const Function * Function::getOverriddenFunctionRecursive(const ::Type* baseType const Variable* Function::getArgumentVar(nonneg int num) const { - for (std::list::const_iterator i = argumentList.begin(); i != argumentList.end(); ++i) { - if (i->index() == num) - return (&*i); - else if (i->index() > num) - return nullptr; - } + if (num < argumentList.size()) + return &argumentList[num]; return nullptr; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 46851df4b..39df19aa6 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -693,7 +693,7 @@ private: /** @brief pointer to scope this variable is in */ const Scope *mScope; - ValueType *mValueType; + const ValueType *mValueType; /** @brief array dimensions */ std::vector mDimensions; @@ -916,7 +916,7 @@ public: const ::Type *retType; ///< function return type const Scope *functionScope; ///< scope of function body const Scope* nestedIn; ///< Scope the function is declared in - std::list argumentList; ///< argument list + std::vector argumentList; ///< argument list nonneg int initArgCount; ///< number of args with default values Type type; ///< constructor, destructor, ... const Token *noexceptArg; ///< noexcept token diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index fbe501e72..6e03992c0 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -42,6 +42,7 @@ + diff --git a/test/testrunner.vcxproj.filters b/test/testrunner.vcxproj.filters index b311a9d80..9fe2f07a4 100644 --- a/test/testrunner.vcxproj.filters +++ b/test/testrunner.vcxproj.filters @@ -220,6 +220,9 @@ Source Files + + Source Files + @@ -250,4 +253,4 @@ Header Files - + \ No newline at end of file