Fix #10412 FN useStlAlgorithm with iterators (#4157)

This commit is contained in:
chrchr-github 2022-10-16 13:46:26 +02:00 committed by GitHub
parent 5628a39b82
commit 3273e51fd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 484 additions and 483 deletions

View File

@ -635,8 +635,8 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
for (const std::string &lib : mSettings->project.guiProject.libraries)
mSettings->libraries.emplace_back(lib);
for (const std::string &ignorePath : mSettings->project.guiProject.excludedPaths)
mIgnoredPaths.emplace_back(ignorePath);
const auto& excludedPaths = mSettings->project.guiProject.excludedPaths;
std::copy(excludedPaths.begin(), excludedPaths.end(), std::back_inserter(mIgnoredPaths));
const std::string platform(mSettings->project.guiProject.platform);

View File

@ -51,6 +51,7 @@
#include <sstream> // IWYU pragma: keep
#include <utility>
#include <vector>
#include <numeric>
#ifdef USE_UNIX_SIGNAL_HANDLING
#include "cppcheckexecutorsig.h"
@ -129,14 +130,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
}
// Output a warning for the user if he tries to exclude headers
bool warn = false;
const std::vector<std::string>& ignored = parser.getIgnoredPaths();
for (const std::string &i : ignored) {
if (Path::isHeader(i)) {
warn = true;
break;
}
}
const bool warn = std::any_of(ignored.begin(), ignored.end(), [](const std::string& i) {
return Path::isHeader(i);
});
if (warn) {
std::cout << "cppcheck: filename exclusion does not apply to header (.h and .hpp) files." << std::endl;
std::cout << "cppcheck: Please use --suppress for ignoring results from the header files." << std::endl;
@ -154,11 +151,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
// filter only for the selected filenames from all project files
std::list<ImportProject::FileSettings> newList;
for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) {
if (matchglobs(mSettings->fileFilters, fsetting.filename)) {
newList.emplace_back(fsetting);
}
}
const std::list<ImportProject::FileSettings>& fileSettings = settings.project.fileSettings;
std::copy_if(fileSettings.begin(), fileSettings.end(), std::back_inserter(newList), [&](const ImportProject::FileSettings& fs) {
return matchglobs(mSettings->fileFilters, fs.filename);
});
if (!newList.empty())
settings.project.fileSettings = newList;
else {
@ -325,10 +321,9 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
// Single process
settings.jointSuppressionReport = true;
std::size_t totalfilesize = 0;
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i) {
totalfilesize += i->second;
}
const std::size_t totalfilesize = std::accumulate(mFiles.begin(), mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair<std::string, std::size_t>& f) {
return v + f.second;
});
std::size_t processedsize = 0;
unsigned int c = 0;

View File

@ -31,11 +31,11 @@
#include "suppressions.h"
#include <algorithm>
#include <numeric>
#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <functional>
#include <iostream>
#include <list>
@ -43,7 +43,8 @@
#include <sys/select.h>
#include <sys/wait.h>
#include <unistd.h>
#include <utility>
#include <fcntl.h>
#ifdef __SVR4 // Solaris
#include <sys/loadavg.h>
@ -217,10 +218,9 @@ unsigned int ProcessExecutor::check()
unsigned int fileCount = 0;
unsigned int result = 0;
std::size_t totalfilesize = 0;
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i) {
totalfilesize += i->second;
}
const std::size_t totalfilesize = std::accumulate(mFiles.begin(), mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair<std::string, std::size_t>& p) {
return v + p.second;
});
std::list<int> rpipes;
std::map<pid_t, std::string> childFile;

View File

@ -49,15 +49,16 @@ class ThreadExecutor::SyncLogForwarder : public ErrorLogger
{
public:
explicit SyncLogForwarder(ThreadExecutor &threadExecutor)
: mThreadExecutor(threadExecutor), mProcessedFiles(0), mTotalFiles(0), mProcessedSize(0), mTotalFileSize(0) {
: mThreadExecutor(threadExecutor), mProcessedFiles(0), mTotalFiles(0), mProcessedSize(0) {
mItNextFile = mThreadExecutor.mFiles.begin();
const std::map<std::string, std::size_t>& files = mThreadExecutor.mFiles;
mItNextFile = files.begin();
mItNextFileSettings = mThreadExecutor.mSettings.project.fileSettings.begin();
mTotalFiles = mThreadExecutor.mFiles.size() + mThreadExecutor.mSettings.project.fileSettings.size();
for (std::map<std::string, std::size_t>::const_iterator i = mThreadExecutor.mFiles.begin(); i != mThreadExecutor.mFiles.end(); ++i) {
mTotalFileSize += i->second;
}
mTotalFiles = files.size() + mThreadExecutor.mSettings.project.fileSettings.size();
mTotalFileSize = std::accumulate(files.begin(), files.end(), std::size_t(0), [](std::size_t v, const std::pair<std::string, std::size_t>& p) {
return v + p.second;
});
}
void reportOut(const std::string &outmsg, Color c) override

View File

@ -398,9 +398,9 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS
continue;
std::list<ErrorMessage::FileLocation> callstack;
for (const QErrorPathItem &path : e.errorPath) {
callstack.emplace_back(path.file.toStdString(), path.info.toStdString(), path.line, path.column);
}
std::transform(e.errorPath.begin(), e.errorPath.end(), std::back_inserter(callstack), [](const QErrorPathItem& path) {
return ErrorMessage::FileLocation(path.file.toStdString(), path.info.toStdString(), path.line, path.column);
});
const std::string f0 = file0.toStdString();
const std::string msg = e.message.toStdString();
const std::string id = e.errorId.toStdString();
@ -411,11 +411,9 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS
bool CheckThread::isSuppressed(const Suppressions::ErrorMessage &errorMessage) const
{
for (const Suppressions::Suppression &suppression : mSuppressions) {
if (suppression.isSuppressed(errorMessage))
return true;
}
return false;
return std::any_of(mSuppressions.begin(), mSuppressions.end(), [&](const Suppressions::Suppression& s) {
return s.isSuppressed(errorMessage);
});
}
QString CheckThread::clangCmd()

View File

@ -110,9 +110,9 @@ void FileList::addExcludeList(const QStringList &paths)
static std::vector<std::string> toStdStringList(const QStringList &stringList)
{
std::vector<std::string> ret;
for (const QString &s : stringList) {
ret.push_back(s.toStdString());
}
std::transform(stringList.begin(), stringList.end(), std::back_inserter(ret), [](const QString& s) {
return s.toStdString();
});
return ret;
}

View File

@ -57,11 +57,13 @@ int main(int argc, char *argv[])
QSettings* settings = new QSettings("Cppcheck", "Cppcheck-GUI", &app);
// Set data dir..
for (const QString& arg : QApplication::arguments()) {
if (arg.startsWith("--data-dir=")) {
settings->setValue("DATADIR", arg.mid(11));
return 0;
}
const QStringList args = QApplication::arguments();
auto it = std::find_if(args.begin(), args.end(), [](const QString& arg) {
return arg.startsWith("--data-dir=");
});
if (it != args.end()) {
settings->setValue("DATADIR", it->mid(11));
return 0;
}
TranslationHandler* th = new TranslationHandler(&app);

View File

@ -451,9 +451,10 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
mIsLogfileLoaded = false;
if (mProjectFile) {
std::vector<std::string> v;
for (const QString &i : mProjectFile->getExcludedPaths()) {
v.push_back(i.toStdString());
}
const QStringList excluded = mProjectFile->getExcludedPaths();
std::transform(excluded.begin(), excluded.end(), std::back_inserter(v), [](const QString& e) {
return e.toStdString();
});
p.ignorePaths(v);
if (!mProjectFile->getAnalyzeAllVsConfigs()) {
@ -554,8 +555,9 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar
if (!checkSettings.buildDir.empty()) {
checkSettings.loadSummaries();
std::list<std::string> sourcefiles;
for (const QString& s: fileNames)
sourcefiles.push_back(s.toStdString());
std::transform(fileNames.begin(), fileNames.end(), std::back_inserter(sourcefiles), [](const QString& s) {
return s.toStdString();
});
AnalyzerInformation::writeFilesTxt(checkSettings.buildDir, sourcefiles, checkSettings.userDefines, checkSettings.project.fileSettings);
}

View File

@ -35,13 +35,13 @@
Check::Check(const std::string &aname)
: mTokenizer(nullptr), mSettings(nullptr), mErrorLogger(nullptr), mName(aname)
{
for (std::list<Check*>::iterator i = instances().begin(); i != instances().end(); ++i) {
if ((*i)->name() > aname) {
instances().insert(i, this);
return;
}
}
instances().push_back(this);
auto it = std::find_if(instances().begin(), instances().end(), [&](const Check* i) {
return i->name() > aname;
});
if (it == instances().end())
instances().push_back(this);
else
instances().insert(it, this);
}
void Check::reportError(const ErrorMessage &errmsg)

View File

@ -418,10 +418,10 @@ static bool isInScope(const Token * tok, const Scope * scope)
const Scope * tokScope = tok->scope();
if (!tokScope)
return false;
for (const Scope * argScope:tokScope->nestedList) {
if (argScope && argScope->isNestedIn(scope))
return true;
}
if (std::any_of(tokScope->nestedList.begin(), tokScope->nestedList.end(), [&](const Scope* argScope) {
return argScope && argScope->isNestedIn(scope);
}))
return true;
}
return false;
}

View File

@ -104,11 +104,9 @@ static bool isVariableCopyNeeded(const Variable &var, Function::Type type)
static bool isVcl(const Settings *settings)
{
for (const std::string &library: settings->libraries) {
if (library == "vcl")
return true;
}
return false;
return std::any_of(settings->libraries.begin(), settings->libraries.end(), [](const std::string& library) {
return library == "vcl";
});
}
static bool isVclTypeInit(const Type *type)
@ -148,17 +146,13 @@ void CheckClass::constructors()
const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">");
bool usedInUnion = false;
for (const Scope &unionScope : mSymbolDatabase->scopeList) {
const bool usedInUnion = std::any_of(mSymbolDatabase->scopeList.begin(), mSymbolDatabase->scopeList.end(), [&](const Scope& unionScope) {
if (unionScope.type != Scope::eUnion)
continue;
for (const Variable &var : unionScope.varlist) {
if (var.type() && var.type()->classScope == scope) {
usedInUnion = true;
break;
}
}
}
return false;
return std::any_of(unionScope.varlist.begin(), unionScope.varlist.end(), [&](const Variable& var) {
return var.type() && var.type()->classScope == scope;
});
});
// There are no constructors.
if (scope->numConstructors == 0 && printStyle && !usedInUnion) {
@ -190,13 +184,9 @@ void CheckClass::constructors()
// #3196 => bailout if there are nested unions
// TODO: handle union variables better
{
bool bailout = false;
for (const Scope * const nestedScope : scope->nestedList) {
if (nestedScope->type == Scope::eUnion) {
bailout = true;
break;
}
}
const bool bailout = std::any_of(scope->nestedList.begin(), scope->nestedList.end(), [](const Scope* nestedScope) {
return nestedScope->type == Scope::eUnion;
});
if (bailout)
continue;
}
@ -352,13 +342,9 @@ void CheckClass::checkExplicitConstructors()
// Is class abstract? Maybe this test is over-simplification, but it will suffice for simple cases,
// and it will avoid false positives.
bool isAbstractClass = false;
for (const Function &func : scope->functionList) {
if (func.isPure()) {
isAbstractClass = true;
break;
}
}
const bool isAbstractClass = std::any_of(scope->functionList.begin(), scope->functionList.end(), [](const Function& func) {
return func.isPure();
});
// Abstract classes can't be instantiated. But if there is C++11
// "misuse" by derived classes then these constructors must be explicit.
@ -633,8 +619,9 @@ bool CheckClass::canNotMove(const Scope *scope)
static void getAllVariableMembers(const Scope *scope, std::vector<const Variable *>& varList)
{
for (const Variable& var: scope->varlist)
varList.push_back(&var);
std::transform(scope->varlist.begin(), scope->varlist.end(), std::back_inserter(varList), [](const Variable& var) {
return &var;
});
if (scope->definedType) {
for (const Type::BaseInfo& baseInfo: scope->definedType->derivedFrom) {
if (scope->definedType == baseInfo.type)
@ -652,8 +639,9 @@ std::vector<CheckClass::Usage> CheckClass::createUsageList(const Scope *scope)
std::vector<const Variable *> varlist;
getAllVariableMembers(scope, varlist);
ret.reserve(varlist.size());
for (const Variable *var: varlist)
ret.emplace_back(var);
std::transform(varlist.begin(), varlist.end(), std::back_inserter(ret), [](const Variable* var) {
return Usage(var);
});
return ret;
}
@ -716,10 +704,11 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope)
if (derivedFrom && derivedFrom->classScope) {
const std::list<Function>& functionList = derivedFrom->classScope->functionList;
for (const Function &func : functionList) {
if (func.tokenDef->str() == tok->str())
return true;
}
if (std::any_of(functionList.begin(), functionList.end(), [&](const Function& func) {
return func.tokenDef->str() == tok->str();
}))
return true;
if (isBaseClassFunc(tok, derivedFrom->classScope))
return true;
}
@ -821,13 +810,11 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
// Calling member variable function?
if (Token::Match(ftok->next(), "%var% . %name% (") && !(ftok->next()->valueType() && ftok->next()->valueType()->pointer)) {
for (const Variable &var : scope->varlist) {
if (var.declarationId() == ftok->next()->varId()) {
/** @todo false negative: we assume function changes variable state */
assignVar(usage, ftok->next()->varId());
break;
}
}
if (std::any_of(scope->varlist.begin(), scope->varlist.end(), [&](const Variable& var) {
return var.declarationId() == ftok->next()->varId();
}))
/** @todo false negative: we assume function changes variable state */
assignVar(usage, ftok->next()->varId());
ftok = ftok->tokAt(2);
}
@ -1860,12 +1847,10 @@ void CheckClass::virtualDestructor()
if (printInconclusive) {
const Function *destructor = scope->getDestructor();
if (destructor && !destructor->hasVirtualSpecifier() && destructor->access == AccessControl::Public) {
for (const Function &func : scope->functionList) {
if (func.hasVirtualSpecifier()) {
inconclusiveErrors.push_back(destructor);
break;
}
}
if (std::any_of(scope->functionList.begin(), scope->functionList.end(), [](const Function& func) {
return func.hasVirtualSpecifier();
}))
inconclusiveErrors.push_back(destructor);
}
}
continue;
@ -2716,9 +2701,10 @@ void CheckClass::virtualFunctionCallInConstructorError(
const char * scopeFunctionTypeName = scopeFunction ? getFunctionTypeName(scopeFunction->type) : "constructor";
ErrorPath errorPath;
std::transform(tokStack.begin(), tokStack.end(), std::back_inserter(errorPath), [](const Token* tok) {
return ErrorPathItem(tok, "Calling " + tok->str());
});
int lineNumber = 1;
for (const Token *tok : tokStack)
errorPath.emplace_back(tok, "Calling " + tok->str());
if (!errorPath.empty()) {
lineNumber = errorPath.front().first->linenr();
errorPath.back().second = funcname + " is a virtual function";
@ -2750,8 +2736,9 @@ void CheckClass::pureVirtualFunctionCallInConstructorError(
const char * scopeFunctionTypeName = scopeFunction ? getFunctionTypeName(scopeFunction->type) : "constructor";
ErrorPath errorPath;
for (const Token *tok : tokStack)
errorPath.emplace_back(tok, "Calling " + tok->str());
std::transform(tokStack.begin(), tokStack.end(), std::back_inserter(errorPath), [](const Token* tok) {
return ErrorPathItem(tok, "Calling " + tok->str());
});
if (!errorPath.empty())
errorPath.back().second = purefuncname + " is a pure virtual function without body";

View File

@ -752,13 +752,9 @@ void CheckCondition::multiCondition2()
// Incomplete code
break;
}
bool changed = false;
for (const int varid : vars) {
if (isVariableChanged(tok1, tok2, varid, nonlocal, mSettings, mTokenizer->isCPP())) {
changed = true;
break;
}
}
const bool changed = std::any_of(vars.begin(), vars.end(), [&](int varid) {
return isVariableChanged(tok1, tok2, varid, nonlocal, mSettings, mTokenizer->isCPP());
});
if (changed)
break;
}

View File

@ -82,11 +82,9 @@ template<std::size_t N>
static bool isVarTokComparison(const Token * tok, const Token ** vartok,
const std::array<std::pair<std::string, std::string>, N>& ops)
{
for (const auto & op : ops) {
if (astIsVariableComparison(tok, op.first, op.second, vartok))
return true;
}
return false;
return std::any_of(ops.begin(), ops.end(), [&](const std::pair<std::string, std::string>& op) {
return astIsVariableComparison(tok, op.first, op.second, vartok);
});
}
//---------------------------------------------------------------------------

View File

@ -450,12 +450,10 @@ void CheckOther::checkRedundantAssignment()
// If there is a custom assignment operator => this is inconclusive
if (tok->astOperand1()->valueType()->typeScope) {
const std::string op = "operator" + tok->str();
for (const Function& f : tok->astOperand1()->valueType()->typeScope->functionList) {
if (f.name() == op) {
inconclusive = true;
break;
}
}
const std::list<Function>& fList = tok->astOperand1()->valueType()->typeScope->functionList;
inconclusive = std::any_of(fList.begin(), fList.end(), [&](const Function& f) {
return f.name() == op;
});
}
// assigning a smart pointer has side effects
if (tok->astOperand1()->valueType()->type == ValueType::SMART_POINTER)
@ -1181,11 +1179,11 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
accumulateSize(cumulatedSize, size, isUnion);
}
for (const Type::BaseInfo &baseInfo : type->derivedFrom) {
return std::accumulate(type->derivedFrom.begin(), type->derivedFrom.end(), cumulatedSize, [&](int v, const Type::BaseInfo& baseInfo) {
if (baseInfo.type && baseInfo.type->classScope)
cumulatedSize += estimateSize(baseInfo.type, settings, symbolDatabase, recursionDepth+1);
}
return cumulatedSize;
v += estimateSize(baseInfo.type, settings, symbolDatabase, recursionDepth + 1);
return v;
});
}
static bool canBeConst(const Variable *var, const Settings* settings)
@ -3463,10 +3461,12 @@ static const Token *findShadowed(const Scope *scope, const std::string &varname,
if (var.name() == varname)
return var.nameToken();
}
for (const Function &f : scope->functionList) {
if (f.type == Function::Type::eFunction && f.name() == varname)
return f.tokenDef;
}
auto it = std::find_if(scope->functionList.begin(), scope->functionList.end(), [&](const Function& f) {
return f.type == Function::Type::eFunction && f.name() == varname;
});
if (it != scope->functionList.end())
return it->tokenDef;
if (scope->type == Scope::eLambda)
return nullptr;
const Token* shadowed = findShadowed(scope->nestedIn, varname, linenr);
@ -3491,16 +3491,14 @@ void CheckOther::checkShadowVariables()
continue;
if (functionScope && functionScope->type == Scope::ScopeType::eFunction && functionScope->function) {
bool shadowArg = false;
for (const Variable &arg : functionScope->function->argumentList) {
if (arg.nameToken() && var.name() == arg.name()) {
shadowError(var.nameToken(), arg.nameToken(), "argument");
shadowArg = true;
break;
}
}
if (shadowArg)
const auto argList = functionScope->function->argumentList;
auto it = std::find_if(argList.begin(), argList.end(), [&](const Variable& arg) {
return arg.nameToken() && var.name() == arg.name();
});
if (it != argList.end()) {
shadowError(var.nameToken(), it->nameToken(), "argument");
continue;
}
}
const Token *shadowed = findShadowed(scope.nestedIn, var.name(), var.nameToken()->linenr());

View File

@ -168,9 +168,11 @@ void CheckSizeof::checkSizeofForPointerSize()
auto hasMultiplication = [](const Token* parTok) -> bool {
while (parTok) { // Allow division if followed by multiplication
if (parTok->isArithmeticalOp() && parTok->str() == "*") {
for (const Token* szTok : { parTok->astOperand1(), parTok->astOperand2() })
if (Token::simpleMatch(szTok, "(") && Token::simpleMatch(szTok->previous(), "sizeof"))
return true;
const Token* szToks[] = { parTok->astOperand1(), parTok->astOperand2() };
if (std::any_of(std::begin(szToks), std::end(szToks), [](const Token* szTok) {
return Token::simpleMatch(szTok, "(") && Token::simpleMatch(szTok->previous(), "sizeof");
}))
return true;
}
parTok = parTok->astParent();
}

View File

@ -2701,6 +2701,13 @@ void CheckStl::useStlAlgorithm()
{
if (!mSettings->severity.isEnabled(Severity::style))
return;
auto checkAssignee = [](const Token* tok) {
if (astIsBool(tok)) // std::accumulate is not a good fit for bool values, std::all/any/none_of return early
return false;
return !astIsContainer(tok); // don't warn for containers, where overloaded operators can be costly
};
for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
// Parse range-based for loop
@ -2710,16 +2717,35 @@ void CheckStl::useStlAlgorithm()
continue;
const Token *bodyTok = tok->next()->link()->next();
const Token *splitTok = tok->next()->astOperand2();
if (!Token::simpleMatch(splitTok, ":"))
continue;
const Token *loopVar = splitTok->previous();
if (loopVar->varId() == 0)
continue;
const Token* loopVar{};
bool isIteratorLoop = false;
if (Token::simpleMatch(splitTok, ":")) {
loopVar = splitTok->previous();
if (loopVar->varId() == 0)
continue;
}
else { // iterator-based loop?
const Token* initTok = getInitTok(tok);
const Token* condTok = getCondTok(tok);
const Token* stepTok = getStepTok(tok);
if (!initTok || !condTok || !stepTok)
continue;
loopVar = Token::Match(condTok, "%comp%") ? condTok->astOperand1() : nullptr;
if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR)
continue;
if (!Token::simpleMatch(initTok, "=") || !Token::Match(initTok->astOperand1(), "%varid%", loopVar->varId()))
continue;
if (!stepTok->isIncDecOp())
continue;
isIteratorLoop = true;
}
// Check for single assignment
bool useLoopVarInAssign;
const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign);
if (assignTok) {
if (!checkAssignee(assignTok->astOperand1()))
continue;
const int assignVarId = assignTok->astOperand1()->varId();
std::string algo;
if (assignVarId == loopVar->varId()) {
@ -2747,7 +2773,7 @@ void CheckStl::useStlAlgorithm()
// Check for container calls
bool useLoopVarInMemCall;
const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall);
if (memberAccessTok) {
if (memberAccessTok && !isIteratorLoop) {
const Token *memberCallTok = memberAccessTok->astOperand2();
const int contVarId = memberAccessTok->astOperand1()->varId();
if (contVarId == loopVar->varId())
@ -2784,6 +2810,8 @@ void CheckStl::useStlAlgorithm()
// Check for single assign
assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign);
if (assignTok) {
if (!checkAssignee(assignTok->astOperand1()))
continue;
const int assignVarId = assignTok->astOperand1()->varId();
std::string algo;
if (assignVarId == loopVar->varId()) {

View File

@ -775,12 +775,11 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
tok = scope->classDef->next();
for (; tok && tok != scope->bodyEnd; tok = tok->next()) {
if (tok->str() == "{" && tok != scope->bodyStart && !tok->previous()->varId()) {
for (const Scope *i : scope->nestedList) {
if (i->bodyStart == tok) { // Find associated scope
checkFunctionVariableUsage_iterateScopes(tok->scope(), variables); // Scan child scope
tok = tok->link();
break;
}
if (std::any_of(scope->nestedList.begin(), scope->nestedList.end(), [&](const Scope* s) {
return s->bodyStart == tok;
})) {
checkFunctionVariableUsage_iterateScopes(tok->scope(), variables); // Scan child scope
tok = tok->link();
}
if (!tok)
break;
@ -1422,13 +1421,10 @@ void CheckUnusedVar::checkStructMemberUsage()
if (scope.bodyEnd->isAttributePacked())
continue;
if (const Preprocessor *preprocessor = mTokenizer->getPreprocessor()) {
bool isPacked = false;
for (const Directive &d: preprocessor->getDirectives()) {
if (d.str == "#pragma pack(1)" && d.file == mTokenizer->list.getFiles().front() && d.linenr < scope.bodyStart->linenr()) {
isPacked=true;
break;
}
}
const auto& directives = preprocessor->getDirectives();
const bool isPacked = std::any_of(directives.begin(), directives.end(), [&](const Directive& d) {
return d.linenr < scope.bodyStart->linenr() && d.str == "#pragma pack(1)" && d.file == mTokenizer->list.getFiles().front();
});
if (isPacked)
continue;
}
@ -1442,20 +1438,12 @@ void CheckUnusedVar::checkStructMemberUsage()
continue;
// bail out if struct is inherited
bool bailout = false;
for (const Scope &derivedScope : symbolDatabase->scopeList) {
if (derivedScope.definedType) {
for (const Type::BaseInfo &derivedFrom : derivedScope.definedType->derivedFrom) {
if (derivedFrom.type == scope.definedType) {
bailout = true;
break;
}
}
}
if (bailout)
break;
}
bool bailout = std::any_of(symbolDatabase->scopeList.begin(), symbolDatabase->scopeList.end(), [&](const Scope& derivedScope) {
const Type* dType = derivedScope.definedType;
return dType && std::any_of(dType->derivedFrom.begin(), dType->derivedFrom.end(), [&](const Type::BaseInfo& derivedFrom) {
return derivedFrom.type == scope.definedType;
});
});
if (bailout)
continue;
@ -1592,10 +1580,10 @@ bool CheckUnusedVar::isRecordTypeWithoutSideEffects(const Type* type)
}
// Derived from type that has side effects?
for (const Type::BaseInfo& derivedFrom : type->derivedFrom) {
if (!isRecordTypeWithoutSideEffects(derivedFrom.type))
return (withoutSideEffects = false);
}
if (std::any_of(type->derivedFrom.begin(), type->derivedFrom.end(), [this](const Type::BaseInfo& derivedFrom) {
return !isRecordTypeWithoutSideEffects(derivedFrom.type);
}))
return (withoutSideEffects = false);
// Is there a member variable with possible side effects
for (const Variable& var : type->classScope->varlist) {
@ -1641,18 +1629,13 @@ bool CheckUnusedVar::isEmptyType(const Type* type)
if (type && type->classScope && type->classScope->numConstructors == 0 &&
(type->classScope->varlist.empty())) {
for (std::vector<Type::BaseInfo>::const_iterator i = type->derivedFrom.begin(); i != type->derivedFrom.end(); ++i) {
if (!isEmptyType(i->type)) {
emptyType=false;
return emptyType;
}
}
emptyType=true;
return emptyType;
return (emptyType = std::all_of(type->derivedFrom.begin(), type->derivedFrom.end(), [this](const Type::BaseInfo& bi) {
return isEmptyType(bi.type);
}));
}
emptyType=false; // unknown types are assumed to be nonempty
return emptyType;
// unknown types are assumed to be nonempty
return (emptyType = false);
}
bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const Token* functionUsageToken,

View File

@ -42,6 +42,7 @@
#include <string>
#include <utility>
#include <vector>
#include <numeric>
static const std::string AccessSpecDecl = "AccessSpecDecl";
static const std::string ArraySubscriptExpr = "ArraySubscriptExpr";
@ -1447,16 +1448,15 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList)
// definition
if (isDefinition()) {
std::vector<AstNodePtr> children2;
for (const AstNodePtr &child: children) {
if (child->nodeType == CXXConstructorDecl ||
child->nodeType == CXXDestructorDecl ||
child->nodeType == CXXMethodDecl ||
child->nodeType == FieldDecl ||
child->nodeType == VarDecl ||
child->nodeType == AccessSpecDecl ||
child->nodeType == TypedefDecl)
children2.push_back(child);
}
std::copy_if(children.begin(), children.end(), std::back_inserter(children2), [](const AstNodePtr& child) {
return child->nodeType == CXXConstructorDecl ||
child->nodeType == CXXDestructorDecl ||
child->nodeType == CXXMethodDecl ||
child->nodeType == FieldDecl ||
child->nodeType == VarDecl ||
child->nodeType == AccessSpecDecl ||
child->nodeType == TypedefDecl;
});
Scope *scope = createScope(tokenList, isStruct ? Scope::ScopeType::eStruct : Scope::ScopeType::eClass, children2, classToken);
const std::string addr = mExtTokens[0];
mData->scopeDecl(addr, scope);
@ -1531,10 +1531,9 @@ static void setValues(Tokenizer *tokenizer, SymbolDatabase *symbolDatabase)
int typeSize = 0;
for (const Variable &var: scope.varlist) {
int mul = 1;
for (const auto &dim: var.dimensions()) {
mul *= dim.num;
}
const int mul = std::accumulate(var.dimensions().begin(), var.dimensions().end(), 1, [](int v, const Dimension& dim) {
return v * dim.num;
});
if (var.valueType())
typeSize += mul * var.valueType()->typeSize(*settings, true);
}

View File

@ -762,12 +762,9 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map<std::str
for (const ProjectConfiguration &p : projectConfigurationList) {
if (!guiProject.checkVsConfigs.empty()) {
bool doChecking = false;
for (const std::string& config : guiProject.checkVsConfigs)
if (config == p.configuration) {
doChecking = true;
break;
}
const bool doChecking = std::any_of(guiProject.checkVsConfigs.begin(), guiProject.checkVsConfigs.end(), [&](const std::string& c) {
return c == p.configuration;
});
if (!doChecking)
continue;
}

View File

@ -1313,12 +1313,10 @@ bool Library::formatstr_function(const Token* ftok) const
int Library::formatstr_argno(const Token* ftok) const
{
const std::map<int, Library::ArgumentChecks>& argumentChecksFunc = functions.at(getFunctionName(ftok)).argumentChecks;
for (const std::pair<const int, Library::ArgumentChecks> & argCheckFunc : argumentChecksFunc) {
if (argCheckFunc.second.formatstr) {
return argCheckFunc.first - 1;
}
}
return -1;
auto it = std::find_if(argumentChecksFunc.begin(), argumentChecksFunc.end(), [](const std::pair<const int, Library::ArgumentChecks>& a) {
return a.second.formatstr;
});
return it == argumentChecksFunc.end() ? -1 : it->first - 1;
}
bool Library::formatstr_scan(const Token* ftok) const
@ -1396,14 +1394,12 @@ bool Library::hasminsize(const Token *ftok) const
{
if (isNotLibraryFunction(ftok))
return false;
const std::unordered_map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
if (it1 == functions.cend())
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
if (it == functions.cend())
return false;
for (const std::pair<const int, Library::ArgumentChecks> & argCheck : it1->second.argumentChecks) {
if (!argCheck.second.minsizes.empty())
return true;
}
return false;
return std::any_of(it->second.argumentChecks.begin(), it->second.argumentChecks.end(), [](const std::pair<const int, Library::ArgumentChecks>& a) {
return !a.second.minsizes.empty();
});
}
Library::ArgumentChecks::Direction Library::getArgDirection(const Token* ftok, int argnr) const

View File

@ -29,6 +29,7 @@
#include <locale>
#include <sstream>
#include <stdexcept>
#include <numeric>
#include <simplecpp.h>
@ -342,11 +343,9 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
unsigned int MathLib::encodeMultiChar(const std::string& str)
{
unsigned int retval = 0;
for (const char it : str) {
retval = (retval << 8) | it;
}
return retval;
return std::accumulate(str.begin(), str.end(), uint32_t(), [](uint32_t v, char c) {
return (v << 8) | c;
});
}
MathLib::bigint MathLib::toLongNumber(const std::string & str)

View File

@ -112,10 +112,9 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
if (!errmsg.empty())
bad->emplace_back(tok->location, std::move(errmsg));
for (const Suppressions::Suppression &s : suppressions) {
if (!s.errorId.empty())
inlineSuppressions.push_back(s);
}
std::copy_if(suppressions.begin(), suppressions.end(), std::back_inserter(inlineSuppressions), [](const Suppressions::Suppression& s) {
return !s.errorId.empty();
});
} else {
//single suppress format
std::string errmsg;

View File

@ -3421,13 +3421,9 @@ bool Type::hasCircularDependencies(std::set<BaseInfo>* ancestors) const
bool Type::findDependency(const Type* ancestor) const
{
if (this==ancestor)
return true;
for (std::vector<BaseInfo>::const_iterator parent=derivedFrom.begin(); parent!=derivedFrom.end(); ++parent) {
if (parent->type && (parent->type == this || parent->type->findDependency(ancestor)))
return true;
}
return false;
return this == ancestor || std::any_of(derivedFrom.begin(), derivedFrom.end(), [&](const BaseInfo& d) {
return d.type && (d.type == this || d.type->findDependency(ancestor));
});
}
bool Type::isDerivedFrom(const std::string & ancestor) const
@ -5570,11 +5566,10 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const
const Scope *SymbolDatabase::findScopeByName(const std::string& name) const
{
for (const Scope &scope: scopeList) {
if (scope.className == name)
return &scope;
}
return nullptr;
auto it = std::find_if(scopeList.begin(), scopeList.end(), [&](const Scope& s) {
return s.className == name;
});
return it == scopeList.end() ? nullptr : &*it;
}
//---------------------------------------------------------------------------
@ -5634,10 +5629,11 @@ const Type* Scope::findType(const std::string & name) const
Scope *Scope::findInNestedListRecursive(const std::string & name)
{
for (Scope *scope: nestedList) {
if (scope->className == name)
return scope;
}
auto it = std::find_if(nestedList.begin(), nestedList.end(), [&](const Scope* s) {
return s->className == name;
});
if (it != nestedList.end())
return *it;
for (Scope* scope: nestedList) {
Scope *child = scope->findInNestedListRecursive(name);
@ -5651,11 +5647,10 @@ Scope *Scope::findInNestedListRecursive(const std::string & name)
const Function *Scope::getDestructor() const
{
for (const Function &f: functionList) {
if (f.type == Function::eDestructor)
return &f;
}
return nullptr;
auto it = std::find_if(functionList.begin(), functionList.end(), [](const Function& f) {
return f.type == Function::eDestructor;
});
return it == functionList.end() ? nullptr : &*it;
}
//---------------------------------------------------------------------------

View File

@ -1074,11 +1074,10 @@ public:
}
const Enumerator * findEnumerator(const std::string & name) const {
for (const Enumerator & i : enumeratorList) {
if (i.name->str() == name)
return &i;
}
return nullptr;
auto it = std::find_if(enumeratorList.begin(), enumeratorList.end(), [&](const Enumerator& i) {
return i.name->str() == name;
});
return it == enumeratorList.end() ? nullptr : &*it;
}
bool isNestedIn(const Scope * outer) const {

View File

@ -736,12 +736,9 @@ static bool areAllParamsTypes(const std::vector<const Token *> &params)
if (params.empty())
return false;
for (const auto *param : params) {
if (!Token::Match(param->previous(), "typename|class %name% ,|>"))
return false;
}
return true;
return std::all_of(params.begin(), params.end(), [](const Token* param) {
return Token::Match(param->previous(), "typename|class %name% ,|>");
});
}
void TemplateSimplifier::getTemplateInstantiations()
@ -1780,15 +1777,14 @@ void TemplateSimplifier::expandTemplate(
type = type->next();
}
// check if type is instantiated
for (const auto & inst : mTemplateInstantiations) {
if (Token::simpleMatch(inst.token(), name.c_str(), name.size())) {
// use the instantiated name
dst->insertToken(name, emptyString, true);
dst->previous()->linenr(start->linenr());
dst->previous()->column(start->column());
start = closing;
break;
}
if (std::any_of(mTemplateInstantiations.begin(), mTemplateInstantiations.end(), [&](const TokenAndName& inst) {
return Token::simpleMatch(inst.token(), name.c_str(), name.size());
})) {
// use the instantiated name
dst->insertToken(name, "", true);
dst->previous()->linenr(start->linenr());
dst->previous()->column(start->column());
start = closing;
}
}
// just copy the token if it wasn't instantiated
@ -3386,22 +3382,17 @@ void TemplateSimplifier::getSpecializations()
// try to locate a matching declaration for each user defined specialization
for (const auto& spec : mTemplateDeclarations) {
if (spec.isSpecialization()) {
bool found = false;
for (const auto& decl : mTemplateDeclarations) {
if (specMatch(spec, decl)) {
mTemplateSpecializationMap[spec.token()] = decl.token();
found = true;
break;
}
}
if (!found) {
for (const auto& decl : mTemplateForwardDeclarations) {
if (specMatch(spec, decl)) {
mTemplateSpecializationMap[spec.token()] = decl.token();
break;
}
}
auto it = std::find_if(mTemplateDeclarations.begin(), mTemplateDeclarations.end(), [&](const TokenAndName& decl) {
return specMatch(spec, decl);
});
if (it != mTemplateDeclarations.end())
mTemplateSpecializationMap[spec.token()] = it->token();
else {
it = std::find_if(mTemplateForwardDeclarations.begin(), mTemplateForwardDeclarations.end(), [&](const TokenAndName& decl) {
return specMatch(spec, decl);
});
if (it != mTemplateForwardDeclarations.end())
mTemplateSpecializationMap[spec.token()] = it->token();
}
}
}
@ -3412,22 +3403,17 @@ void TemplateSimplifier::getPartialSpecializations()
// try to locate a matching declaration for each user defined partial specialization
for (const auto& spec : mTemplateDeclarations) {
if (spec.isPartialSpecialization()) {
bool found = false;
for (const auto& decl : mTemplateDeclarations) {
if (specMatch(spec, decl)) {
mTemplatePartialSpecializationMap[spec.token()] = decl.token();
found = true;
break;
}
}
if (!found) {
for (const auto& decl : mTemplateForwardDeclarations) {
if (specMatch(spec, decl)) {
mTemplatePartialSpecializationMap[spec.token()] = decl.token();
break;
}
}
auto it = std::find_if(mTemplateDeclarations.begin(), mTemplateDeclarations.end(), [&](const TokenAndName& decl) {
return specMatch(spec, decl);
});
if (it != mTemplateDeclarations.end())
mTemplatePartialSpecializationMap[spec.token()] = it->token();
else {
it = std::find_if(mTemplateForwardDeclarations.begin(), mTemplateForwardDeclarations.end(), [&](const TokenAndName& decl) {
return specMatch(spec, decl);
});
if (it != mTemplateForwardDeclarations.end())
mTemplatePartialSpecializationMap[spec.token()] = it->token();
}
}
}

View File

@ -1689,24 +1689,21 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
else
out << "\n\n##Value flow" << std::endl;
for (const Token *tok = this; tok; tok = tok->next()) {
if (!tok->mImpl->mValues)
const auto* const values = tok->mImpl->mValues;
if (!values)
continue;
if (tok->mImpl->mValues->empty()) // Values might be removed by removeContradictions
if (values->empty()) // Values might be removed by removeContradictions
continue;
if (xml)
out << " <values id=\"" << tok->mImpl->mValues << "\">" << std::endl;
out << " <values id=\"" << values << "\">" << std::endl;
else if (line != tok->linenr())
out << "Line " << tok->linenr() << std::endl;
line = tok->linenr();
if (!xml) {
const ValueFlow::Value::ValueKind valueKind = tok->mImpl->mValues->front().valueKind;
bool same = true;
for (const ValueFlow::Value &value : *tok->mImpl->mValues) {
if (value.valueKind != valueKind) {
same = false;
break;
}
}
ValueFlow::Value::ValueKind valueKind = values->front().valueKind;
const bool same = std::all_of(values->begin(), values->end(), [&](const ValueFlow::Value& value) {
return value.valueKind == valueKind;
});
out << " " << tok->str() << " ";
if (same) {
switch (valueKind) {
@ -1722,10 +1719,10 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
break;
}
}
if (tok->mImpl->mValues->size() > 1U)
if (values->size() > 1U)
out << '{';
}
for (const ValueFlow::Value &value : *tok->mImpl->mValues) {
for (const ValueFlow::Value& value : *values) {
if (xml) {
out << " <value ";
switch (value.valueType) {
@ -1785,14 +1782,14 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
}
else {
if (&value != &tok->mImpl->mValues->front())
if (&value != &values->front())
out << ",";
out << value.toString();
}
}
if (xml)
out << " </values>" << std::endl;
else if (tok->mImpl->mValues->size() > 1U)
else if (values->size() > 1U)
out << '}' << std::endl;
else
out << std::endl;

View File

@ -1877,11 +1877,9 @@ namespace {
}
bool hasChild(const std::string &childName) const {
for (const auto & child : children) {
if (child.name == childName)
return true;
}
return false;
return std::any_of(children.begin(), children.end(), [&](const ScopeInfo3& child) {
return child.name == childName;
});
}
const ScopeInfo3 * findInChildren(const std::string & scope) const {
@ -1901,10 +1899,11 @@ namespace {
const ScopeInfo3 * tempScope = this;
while (tempScope) {
// check children
for (const auto & child : tempScope->children) {
if (&child != this && child.type == Record && (child.name == scope || child.fullName == scope))
return &child;
}
auto it = std::find_if(tempScope->children.begin(), tempScope->children.end(), [&](const ScopeInfo3& child) {
return &child != this && child.type == Record && (child.name == scope || child.fullName == scope);
});
if (it != tempScope->children.end())
return &*it;
// check siblings for same name
if (tempScope->parent) {
for (const auto &sibling : tempScope->parent->children) {
@ -2181,15 +2180,17 @@ namespace {
const ScopeInfo3 * tempScope = scopeInfo;
while (tempScope) {
//if (!tempScope->parent->usingNamespaces.empty()) {
if (!tempScope->usingNamespaces.empty()) {
const std::set<std::string>& usingNS = tempScope->usingNamespaces;
if (!usingNS.empty()) {
if (qualification.empty()) {
if (tempScope->usingNamespaces.find(scope) != tempScope->usingNamespaces.end())
if (usingNS.find(scope) != usingNS.end())
return true;
} else {
for (const auto &ns : tempScope->usingNamespaces) {
if (scope == ns + " :: " + qualification)
return true;
}
const std::string suffix = " :: " + qualification;
if (std::any_of(usingNS.begin(), usingNS.end(), [&](const std::string& ns) {
return scope == ns + suffix;
}))
return true;
}
}
tempScope = tempScope->parent;
@ -4427,8 +4428,9 @@ void Tokenizer::setVarIdPass2()
continue;
// What member variables are there in this class?
for (const Token *it : classnameTokens)
scopeInfo.emplace_back(it->str(), tokStart->link());
std::transform(classnameTokens.begin(), classnameTokens.end(), std::back_inserter(scopeInfo), [&](const Token* tok) {
return ScopeInfo2(tok->str(), tokStart->link());
});
for (Token *tok2 = tokStart->next(); tok2 && tok2 != tokStart->link(); tok2 = tok2->next()) {
// skip parentheses..
@ -9811,13 +9813,11 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const
{
if (!mPreprocessor)
return false;
for (const Directive &d: mPreprocessor->getDirectives()) {
if (d.linenr >= start->linenr() &&
d.linenr <= end->linenr() &&
d.str.compare(0,3,"#if") == 0 &&
start->fileIndex() < list.getFiles().size() &&
d.file == list.getFiles()[start->fileIndex()])
return true;
}
return false;
return std::any_of(mPreprocessor->getDirectives().begin(), mPreprocessor->getDirectives().end(), [&](const Directive& d) {
return d.str.compare(0, 3, "#if") == 0 &&
d.linenr >= start->linenr() &&
d.linenr <= end->linenr() &&
start->fileIndex() < list.getFiles().size() &&
d.file == list.getFiles()[start->fileIndex()];
});
}

View File

@ -115,11 +115,9 @@ inline static bool isStringCharLiteral(const std::string &str, char q)
return false;
static const std::array<std::string, 5> suffixes{"", "u8", "u", "U", "L"};
for (const std::string & p: suffixes) {
if (isPrefixStringCharLiteral(str, q, p))
return true;
}
return false;
return std::any_of(suffixes.begin(), suffixes.end(), [&](const std::string& p) {
return isPrefixStringCharLiteral(str, q, p);
});
}
inline static bool isStringLiteral(const std::string &str)

View File

@ -3408,10 +3408,11 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
!Token::simpleMatch(getArgumentStart(tok), ",") && getArgumentStart(tok)->valueType()) {
const Token* vartok = getArgumentStart(tok);
auto vts = getParentValueTypes(tok);
for (const ValueType& vt : vts) {
if (vt.isTypeEqual(vartok->valueType()))
return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1);
}
auto it = std::find_if(vts.begin(), vts.end(), [&](const ValueType& vt) {
return vt.isTypeEqual(vartok->valueType());
});
if (it != vts.end())
return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1);
}
return {{tok, std::move(errorPath)}};
}
@ -5333,16 +5334,17 @@ static void valueFlowForwardConst(Token* start,
[&] {
// Follow references
auto refs = followAllReferences(tok);
for (const ReferenceToken& ref : refs) {
if (ref.token->varId() == var->declarationId()) {
for (ValueFlow::Value value : values) {
if (refs.size() > 1)
value.setInconclusive();
value.errorPath.insert(value.errorPath.end(), ref.errors.begin(), ref.errors.end());
setTokenValue(tok, value, settings);
}
return;
auto it = std::find_if(refs.begin(), refs.end(), [&](const ReferenceToken& ref) {
return ref.token->varId() == var->declarationId();
});
if (it != refs.end()) {
for (ValueFlow::Value value : values) {
if (refs.size() > 1)
value.setInconclusive();
value.errorPath.insert(value.errorPath.end(), it->errors.begin(), it->errors.end());
setTokenValue(tok, value, settings);
}
return;
}
// Follow symbolic vaues
for (const ValueFlow::Value& v : tok->values()) {
@ -6949,11 +6951,9 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
if (!scope)
return false;
if (scope->type == Scope::eLambda) {
for (const auto& p:values) {
if (!p.second.isLifetimeValue())
return false;
}
return true;
return std::all_of(values.begin(), values.end(), [](const std::pair<nonneg int, ValueFlow::Value>& p) {
return p.second.isLifetimeValue();
});
} else if (scope->type == Scope::eIf || scope->type == Scope::eElse || scope->type == Scope::eWhile ||
scope->type == Scope::eFor) {
auto pred = [](const ValueFlow::Value& value) {
@ -7033,16 +7033,11 @@ bool productParams(const std::unordered_map<Key, std::list<ValueFlow::Value>>& v
for (const auto& arg:args) {
if (arg.empty())
continue;
bool skip = false;
// Make sure all arguments are the same path
const MathLib::bigint path = arg.begin()->second.path;
for (const auto& p:arg) {
if (p.second.path != path) {
skip = true;
break;
}
}
if (skip)
if (std::any_of(arg.begin(), arg.end(), [&](const std::pair<Key, ValueFlow::Value>& p) {
return p.second.path != path;
}))
continue;
f(arg);
}

View File

@ -1784,7 +1784,7 @@ private:
" }\n"
" return 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:10]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
}
void iteratorExpression() {
@ -1988,7 +1988,7 @@ private:
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:6]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
// #10012
check("struct a {\n"
@ -2856,7 +2856,9 @@ private:
" sum += *it;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5] -> [test.cpp:3] -> [test.cpp:8]: (error) Using iterator to local container 'ints' that may be invalid.\n", errout.str());
ASSERT_EQUALS("[test.cpp:10]: (style) Consider using std::accumulate algorithm instead of a raw loop.\n"
"[test.cpp:4] -> [test.cpp:5] -> [test.cpp:3] -> [test.cpp:8]: (error) Using iterator to local container 'ints' that may be invalid.\n",
errout.str());
}
void pushback9() {
@ -3702,7 +3704,7 @@ private:
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
check("function f1(std::list<int> &l1) {\n"
" for(std::list<int>::iterator i = l1.begin(); i != l1.end(); i++) {\n"
@ -3712,7 +3714,7 @@ private:
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
}
void missingInnerComparison5() {
@ -4629,7 +4631,7 @@ private:
" return s.erase(it);\n"
" return s.end();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str());
}
void dereferenceInvalidIterator2() {
@ -4769,7 +4771,7 @@ private:
" b &= f(x);\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool f(int);\n"
"void foo() {\n"
@ -4778,7 +4780,7 @@ private:
" b |= f(x);\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool f(int);\n"
"void foo() {\n"
@ -4787,7 +4789,7 @@ private:
" b = b && f(x);\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool f(int);\n"
"void foo() {\n"
@ -4796,7 +4798,7 @@ private:
" b = b || f(x);\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:5]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
" int n = 0;\n"
@ -4805,6 +4807,63 @@ private:
"}\n",
true);
ASSERT_EQUALS("", errout.str());
check("std::size_t f(const std::map<std::string, std::size_t>& m) {\n" // #10412
" std::size_t t = 0;\n"
" for (std::map<std::string, std::size_t>::const_iterator i = m.begin(); i != m.end(); ++i) {\n"
" t += i->second;\n"
" }\n"
" for (std::map<std::string, std::size_t>::const_iterator i = m.begin(); i != m.end(); i++) {\n"
" t += i->second;\n"
" }\n"
" return t; \n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Consider using std::accumulate algorithm instead of a raw loop.\n"
"[test.cpp:7]: (style) Consider using std::accumulate algorithm instead of a raw loop.\n",
errout.str());
check("int g(const std::vector<int>& v) {\n"
" int t = 0;\n"
" for (auto i = v.begin(); i != v.end(); ++i) {\n"
" t += *i;\n"
" }\n"
" return t;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Consider using std::accumulate algorithm instead of a raw loop.\n", errout.str());
check("auto g(const std::vector<int>& v) {\n"
" std::vector<std::vector<int>::iterator> r;\n"
" for (auto i = v.begin(); i != v.end(); ++i) {\n"
" r.push_back(i);\n"
" }\n"
" return r;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("std::string f(std::vector<std::string> v) {\n"
" std::string ret;\n"
" for (const std::string& s : v)\n"
" ret += s + '\\n';\n"
" return ret;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("std::string f(const std::string& s) {\n"
" std::string ret;\n"
" for (char c : s)\n"
" if (c != ' ')\n"
" ret += i;\n"
" return ret;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("int f(const std::vector<int>& v) {\n"
" int sum = 0;\n"
" for (auto it = v.begin(); it != v.end(); it += 2)\n"
" sum += *it;\n"
" return sum;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void loopAlgoContainerInsert() {
@ -5038,7 +5097,7 @@ private:
" return true;\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:6]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool pred(int x);\n"
"bool foo() {\n"
@ -5051,7 +5110,7 @@ private:
" return true;\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:6]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool pred(int x);\n"
"bool foo() {\n"
@ -5064,7 +5123,7 @@ private:
" return true;\n"
"}\n",
true);
ASSERT_EQUALS("[test.cpp:6]: (style) Consider using std::any_of, std::all_of, std::none_of, or std::accumulate algorithm instead of a raw loop.\n", errout.str());
ASSERT_EQUALS("", errout.str());
check("bool pred(int x);\n"
"bool foo() {\n"

View File

@ -38,6 +38,7 @@
#include <string>
#include <utility>
#include <vector>
#include <numeric>
class TestSuppressions : public TestFixture {
public:
@ -194,10 +195,10 @@ private:
EXPECT_EQ("", r);
}
unsigned int exitCode = 0;
for (std::map<std::string, std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
exitCode |= cppCheck.check(file->first, file->second);
}
unsigned int exitCode = std::accumulate(files.begin(), files.end(), 0U, [&](unsigned int v, const std::pair<std::string, std::string>& f) {
return v | cppCheck.check(f.first, f.second);
});
if (cppCheck.analyseWholeProgram())
exitCode |= settings.exitCode;

View File

@ -108,10 +108,11 @@ private:
currScope = currScope->nestedIn;
}
while (currScope) {
for (const Function & i : currScope->functionList) {
if (i.tokenDef->str() == str)
return &i;
}
auto it = std::find_if(currScope->functionList.begin(), currScope->functionList.end(), [&](const Function& f) {
return f.tokenDef->str() == str;
});
if (it != currScope->functionList.end())
return &*it;
currScope = currScope->nestedIn;
}
return nullptr;
@ -2652,13 +2653,10 @@ private:
"namespace barney { X::X(int) { } }");
// Locate the scope for the class..
const Scope *scope = nullptr;
for (const Scope & it : db->scopeList) {
if (it.isClassOrStruct()) {
scope = &it;
break;
}
}
auto it = std::find_if(db->scopeList.begin(), db->scopeList.end(), [](const Scope& s) {
return s.isClassOrStruct();
});
const Scope *scope = (it == db->scopeList.end()) ? nullptr : &*it;
ASSERT(scope != nullptr);
if (!scope)
@ -2686,13 +2684,10 @@ private:
"}");
// Locate the scope for the class..
const Scope *scope = nullptr;
for (const Scope & it : db->scopeList) {
if (it.isClassOrStruct()) {
scope = &it;
break;
}
}
auto it = std::find_if(db->scopeList.begin(), db->scopeList.end(), [](const Scope& s) {
return s.isClassOrStruct();
});
const Scope* scope = (it == db->scopeList.end()) ? nullptr : &*it;
ASSERT(scope != nullptr);
if (!scope)
@ -2975,11 +2970,10 @@ private:
ASSERT_EQUALS(4U, db->scopeList.size());
// Find the scope for the Fred struct..
const Scope *fredScope = nullptr;
for (const Scope & scope : db->scopeList) {
if (scope.isClassOrStruct() && scope.className == "Fred")
fredScope = &scope;
}
auto it = std::find_if(db->scopeList.begin(), db->scopeList.end(), [&](const Scope& scope) {
return scope.isClassOrStruct() && scope.className == "Fred";
});
const Scope* fredScope = (it == db->scopeList.end()) ? nullptr : &*it;
ASSERT(fredScope != nullptr);
// The struct Fred has two functions, a constructor and a destructor
@ -2988,11 +2982,11 @@ private:
// Get linenumbers where the bodies for the constructor and destructor are..
unsigned int constructor = 0;
unsigned int destructor = 0;
for (const Function & it : fredScope->functionList) {
if (it.type == Function::eConstructor)
constructor = it.token->linenr(); // line number for constructor body
if (it.type == Function::eDestructor)
destructor = it.token->linenr(); // line number for destructor body
for (const Function& f : fredScope->functionList) {
if (f.type == Function::eConstructor)
constructor = f.token->linenr(); // line number for constructor body
if (f.type == Function::eDestructor)
destructor = f.token->linenr(); // line number for destructor body
}
// The body for the constructor is located at line 5..
@ -5099,9 +5093,9 @@ private:
ASSERT_EQUALS(1, db->scopeList.front().varlist.size());
auto list = db->scopeList;
list.pop_front();
for (const auto &scope : list) {
ASSERT_EQUALS(0, scope.varlist.size());
}
ASSERT_EQUALS(true, std::all_of(list.begin(), list.end(), [](const Scope& scope) {
return scope.varlist.empty();
}));
}
void createSymbolDatabaseFindAllScopes4()

View File

@ -741,10 +741,9 @@ private:
append_vector(test_ops, logicalOps);
append_vector(test_ops, assignmentOps);
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
ASSERT_EQUALS(true, MatchCheck(*test_op, "%op%"));
}
ASSERT_EQUALS(true, std::all_of(test_ops.begin(), test_ops.end(), [&](const std::string& s) {
return MatchCheck(s, "%op%");
}));
// Negative test against other operators
std::vector<std::string> other_ops;
@ -763,10 +762,9 @@ private:
append_vector(test_ops, comparisonOps);
append_vector(test_ops, logicalOps);
std::vector<std::string>::const_iterator test_op, test_ops_end = test_ops.end();
for (test_op = test_ops.begin(); test_op != test_ops_end; ++test_op) {
ASSERT_EQUALS(true, MatchCheck(*test_op, "%cop%"));
}
ASSERT_EQUALS(true, std::all_of(test_ops.begin(), test_ops.end(), [&](const std::string& s) {
return MatchCheck(s, "%cop%");
}));
// Negative test against other operators
std::vector<std::string> other_ops;

View File

@ -304,10 +304,10 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.isIntValue() && !v.isImpossible() && v.intvalue == value)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isIntValue() && !v.isImpossible() && v.intvalue == value;
}))
return true;
}
}
@ -323,11 +323,10 @@ private:
for (const Token* tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value& v : tok->values()) {
if (v.isSymbolicValue() && !v.isImpossible() && v.intvalue == value &&
v.tokvalue->expressionString() == expr)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isSymbolicValue() && !v.isImpossible() && v.intvalue == value && v.tokvalue->expressionString() == expr;
}))
return true;
}
}
@ -342,11 +341,10 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.isFloatValue() && !v.isImpossible() && v.floatValue >= value - diff &&
v.floatValue <= value + diff)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isFloatValue() && !v.isImpossible() && v.floatValue >= value - diff && v.floatValue <= value + diff;
}))
return true;
}
}
@ -384,12 +382,13 @@ private:
std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
const std::size_t len = strlen(value);
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.valueType == type && Token::simpleMatch(v.tokvalue, value, strlen(value)))
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.valueType == type && Token::simpleMatch(v.tokvalue, value, len);
}))
return true;
}
}
@ -403,12 +402,13 @@ private:
std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
const std::size_t len = strlen(value);
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.isLifetimeValue() && v.lifetimeScope == lifetimeScope && Token::simpleMatch(v.tokvalue, value, strlen(value)))
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isLifetimeValue() && v.lifetimeScope == lifetimeScope && Token::simpleMatch(v.tokvalue, value, len);
}))
return true;
}
}
@ -423,10 +423,10 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.valueType == type && v.intvalue == value)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.valueType == type && v.intvalue == value;
}))
return true;
}
}
@ -441,10 +441,10 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.isMovedValue() && v.moveKind == moveKind)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isMovedValue() && v.moveKind == moveKind;
}))
return true;
}
}
@ -460,10 +460,10 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.isIntValue() && v.intvalue == value && v.condition)
return true;
}
if (std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) {
return v.isIntValue() && v.intvalue == value && v.condition;
}))
return true;
}
}
@ -4590,11 +4590,10 @@ private:
}
bool isNotKnownValues(const char code[], const char str[]) {
for (const ValueFlow::Value &v : tokenValues(code, str)) {
if (v.isKnown())
return false;
}
return true;
const auto& values = tokenValues(code, str);
return std::none_of(values.begin(), values.end(), [](const ValueFlow::Value& v) {
return v.isKnown();
});
}
void knownValue() {