parent
5628a39b82
commit
3273e51fd5
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
12
gui/main.cpp
12
gui/main.cpp
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -736,12 +736,9 @@ static bool areAllParamsTypes(const std::vector<const Token *> ¶ms)
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 = ⁢
|
||||
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 = ⁢
|
||||
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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue