LCppC backports: Refactorizations/Optimizations (#4204)
This commit is contained in:
parent
0e1cd8b2ac
commit
d81a758850
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue