LCppC backports: Refactorizations/Optimizations (#4204)

This commit is contained in:
PKEuS 2022-08-21 17:21:02 +02:00 committed by GitHub
parent 0e1cd8b2ac
commit d81a758850
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 74 additions and 46 deletions

View File

@ -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<Variable>* setOfVars[] = {&scope->varlist, fun ? &fun->argumentList : nullptr};
for (const std::list<Variable>* 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;
}

View File

@ -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

View File

@ -162,8 +162,6 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string>
continue;
if (var.isArray()) {
Alloc alloc = ARRAY;
const std::map<nonneg int, VariableValue> 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<std::string>
break;
}
}
if (!init)
if (!init) {
Alloc alloc = ARRAY;
const std::map<nonneg int, VariableValue> 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<nonneg int,VariableValue>::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();

View File

@ -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<Variable>::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);
}

View File

@ -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)

View File

@ -22,12 +22,14 @@
#define clangimportH
//---------------------------------------------------------------------------
#include "config.h"
#include <istream>
class Tokenizer;
namespace clangimport {
void parseClangAstDump(Tokenizer *tokenizer, std::istream &f);
void CPPCHECKLIB parseClangAstDump(Tokenizer *tokenizer, std::istream &f);
}
#endif

View File

@ -106,8 +106,10 @@
<ItemGroup>
<ClInclude Include="..\externals\simplecpp\simplecpp.h" />
<ClInclude Include="..\externals\tinyxml2\tinyxml2.h" />
<ClInclude Include="analyzer.h" />
<ClInclude Include="analyzerinfo.h" />
<ClInclude Include="astutils.h" />
<ClInclude Include="calculate.h" />
<ClInclude Include="check.h" />
<ClInclude Include="check64bit.h" />
<ClInclude Include="checkassert.h" />
@ -141,17 +143,22 @@
<ClInclude Include="ctu.h" />
<ClInclude Include="errorlogger.h" />
<ClInclude Include="errortypes.h" />
<ClInclude Include="forwardanalyzer.h" />
<ClInclude Include="infer.h" />
<ClInclude Include="library.h" />
<ClInclude Include="mathlib.h" />
<ClInclude Include="path.h" />
<ClInclude Include="pathanalysis.h" />
<ClInclude Include="pathmatch.h" />
<ClInclude Include="platform.h" />
<ClInclude Include="precompiled.h" />
<ClInclude Include="preprocessor.h" />
<ClInclude Include="importproject.h" />
<ClInclude Include="programmemory.h" />
<ClInclude Include="reverseanalyzer.h" />
<ClInclude Include="settings.h" />
<ClInclude Include="smallvector.h" />
<ClInclude Include="standards.h" />
<ClInclude Include="summaries.h" />
<ClInclude Include="suppressions.h" />
<ClInclude Include="symboldatabase.h" />
@ -163,6 +170,7 @@
<ClInclude Include="tokenrange.h" />
<ClInclude Include="utils.h" />
<ClInclude Include="valueflow.h" />
<ClInclude Include="valueptr.h" />
<ClInclude Include="version.h" />
</ItemGroup>
<ItemGroup>

View File

@ -370,6 +370,30 @@
<ClInclude Include="infer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="analyzer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="calculate.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="forwardanalyzer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pathanalysis.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="reverseanalyzer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="smallvector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="standards.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="valueptr.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
@ -377,4 +401,4 @@
<ItemGroup>
<Natvis Include="cppcheck.natvis" />
</ItemGroup>
</Project>
</Project>

View File

@ -4272,12 +4272,8 @@ const Function * Function::getOverriddenFunctionRecursive(const ::Type* baseType
const Variable* Function::getArgumentVar(nonneg int num) const
{
for (std::list<Variable>::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;
}

View File

@ -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<Dimension> 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<Variable> argumentList; ///< argument list
std::vector<Variable> argumentList; ///< argument list
nonneg int initArgCount; ///< number of args with default values
Type type; ///< constructor, destructor, ...
const Token *noexceptArg; ///< noexcept token

View File

@ -42,6 +42,7 @@
<ClCompile Include="testboost.cpp" />
<ClCompile Include="testbufferoverrun.cpp" />
<ClCompile Include="testcharvar.cpp" />
<ClCompile Include="testclangimport.cpp" />
<ClCompile Include="testclass.cpp" />
<ClCompile Include="testcmdlineparser.cpp" />
<ClCompile Include="testcondition.cpp" />

View File

@ -220,6 +220,9 @@
<ClCompile Include="testtokenrange.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="testclangimport.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="options.h">
@ -250,4 +253,4 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>