From 643d2e6724b4cf6425ed098eb09a810d0e928a60 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 31 May 2022 15:32:17 +0200 Subject: [PATCH 01/44] Fix #10412 FN useStlAlgorithm with iterators --- lib/checkstl.cpp | 22 ++++++++++++++++++---- test/teststl.cpp | 28 ++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index a5ad67d43a2..fe3e4bb3e43 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2610,10 +2610,24 @@ 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 (!Token::Match(loopVar, "%var%")) + const Token* loopVar{}; + if (Token::simpleMatch(splitTok, ":")) { + loopVar = splitTok->previous(); + if (!Token::Match(loopVar, "%var%")) + continue; + } + else if (Token::simpleMatch(splitTok, ";")) { // iterator-based loop + loopVar = splitTok->next(); + if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR) + continue; + const Token* initAssign = splitTok->astOperand1(); + if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%var%", loopVar->varId())) + continue; + const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; + if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op% ", loopVar->varId()))) + continue; + } + else continue; // Check for single assignment diff --git a/test/teststl.cpp b/test/teststl.cpp index 35f0c388843..7e4e491e7dc 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1755,7 +1755,7 @@ class TestStl : public TestFixture { " }\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() { @@ -1959,7 +1959,7 @@ class TestStl : public TestFixture { " }\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" @@ -2824,7 +2824,9 @@ class TestStl : public TestFixture { " 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() { @@ -3675,7 +3677,7 @@ class TestStl : public TestFixture { " }\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 &l1) {\n" " for(std::list::iterator i = l1.begin(); i != l1.end(); i++) {\n" @@ -3685,7 +3687,7 @@ class TestStl : public TestFixture { " }\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() { @@ -4469,7 +4471,7 @@ class TestStl : public TestFixture { " 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() { @@ -4645,6 +4647,20 @@ class TestStl : public TestFixture { "}\n", true); ASSERT_EQUALS("", errout.str()); + + check("std::size_t f(const std::map& m) {\n" + " std::size_t t = 0;\n" + " for (std::map::const_iterator i = m.begin(); i != m.end(); ++i) {\n" + " t += i->second;\n" + " }\n" + " for (std::map::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()); } void loopAlgoContainerInsert() { From 9d581776deb217e7855cc376ec6e5ebc88af9c1f Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 31 May 2022 15:34:56 +0200 Subject: [PATCH 02/44] Add test --- test/teststl.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/teststl.cpp b/test/teststl.cpp index 7e4e491e7dc..cb7498de484 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4648,7 +4648,7 @@ class TestStl : public TestFixture { true); ASSERT_EQUALS("", errout.str()); - check("std::size_t f(const std::map& m) {\n" + check("std::size_t f(const std::map& m) {\n" // #10412 " std::size_t t = 0;\n" " for (std::map::const_iterator i = m.begin(); i != m.end(); ++i) {\n" " t += i->second;\n" @@ -4661,6 +4661,15 @@ class TestStl : public TestFixture { 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& 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()); } void loopAlgoContainerInsert() { From 2e98abb89637a7336e4ca68f50b8095ef9329e1a Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 31 May 2022 16:00:04 +0200 Subject: [PATCH 03/44] Remove whitespace --- lib/checkstl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index fe3e4bb3e43..2b8169efc2f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2624,7 +2624,7 @@ void CheckStl::useStlAlgorithm() if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%var%", loopVar->varId())) continue; const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; - if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op% ", loopVar->varId()))) + if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op%", loopVar->varId()))) continue; } else From 87d62c6e65badea12826884b2d2bf849e75e592f Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 31 May 2022 19:40:34 +0200 Subject: [PATCH 04/44] Use %varid% --- lib/checkstl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 2b8169efc2f..207e432fb99 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2621,7 +2621,7 @@ void CheckStl::useStlAlgorithm() if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR) continue; const Token* initAssign = splitTok->astOperand1(); - if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%var%", loopVar->varId())) + if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%varid%", loopVar->varId())) continue; const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op%", loopVar->varId()))) From e133b550ce260be6beda12f748d87dce0422c9f3 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 1 Jun 2022 11:12:01 +0200 Subject: [PATCH 05/44] Use AST --- lib/checkstl.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 207e432fb99..a111e584520 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2616,12 +2616,13 @@ void CheckStl::useStlAlgorithm() if (!Token::Match(loopVar, "%var%")) continue; } - else if (Token::simpleMatch(splitTok, ";")) { // iterator-based loop - loopVar = splitTok->next(); + else if (Token::simpleMatch(splitTok, ";") && Token::simpleMatch(splitTok->astOperand2(), ";")) { // iterator-based loop + const Token* cmp = splitTok->astOperand2()->astOperand1(); + loopVar = Token::Match(cmp, "%cmp%") ? cmp->astOperand1() : nullptr; if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR) continue; - const Token* initAssign = splitTok->astOperand1(); - if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%varid%", loopVar->varId())) + const Token* init = splitTok->astOperand1(); + if (!Token::simpleMatch(init, "=") || !Token::Match(init->astOperand1(), "%varid%", loopVar->varId())) continue; const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op%", loopVar->varId()))) From 84b90a60f810d65d952e230b655157e8c8d9eadd Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 1 Jun 2022 12:01:56 +0200 Subject: [PATCH 06/44] Use %comp% --- lib/checkstl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index a111e584520..a879f7ff621 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2617,8 +2617,8 @@ void CheckStl::useStlAlgorithm() continue; } else if (Token::simpleMatch(splitTok, ";") && Token::simpleMatch(splitTok->astOperand2(), ";")) { // iterator-based loop - const Token* cmp = splitTok->astOperand2()->astOperand1(); - loopVar = Token::Match(cmp, "%cmp%") ? cmp->astOperand1() : nullptr; + const Token* comp = splitTok->astOperand2()->astOperand1(); + loopVar = Token::Match(comp, "%comp%") ? comp->astOperand1() : nullptr; if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR) continue; const Token* init = splitTok->astOperand1(); From f534198e5b7b7ca7ca2368768ff5223938f34c39 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Jun 2022 12:50:45 +0200 Subject: [PATCH 07/44] Don't warn if iterators are stored --- lib/checkstl.cpp | 4 +++- test/teststl.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index a879f7ff621..1af905c34ba 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2611,6 +2611,7 @@ void CheckStl::useStlAlgorithm() const Token *bodyTok = tok->next()->link()->next(); const Token *splitTok = tok->next()->astOperand2(); const Token* loopVar{}; + bool isIteratorLoop = false; if (Token::simpleMatch(splitTok, ":")) { loopVar = splitTok->previous(); if (!Token::Match(loopVar, "%var%")) @@ -2627,6 +2628,7 @@ void CheckStl::useStlAlgorithm() const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op%", loopVar->varId()))) continue; + isIteratorLoop = true; } else continue; @@ -2662,7 +2664,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()) diff --git a/test/teststl.cpp b/test/teststl.cpp index cb7498de484..abf6181c5ab 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4670,6 +4670,15 @@ class TestStl : public TestFixture { " 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& v) {\n" + " std::vector::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()); } void loopAlgoContainerInsert() { From cfb9e38096c6ceeb152209d4b79995852a51c5cd Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 7 Jun 2022 15:30:03 +0200 Subject: [PATCH 08/44] Use helper functions --- lib/checkstl.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 1af905c34ba..d8f80edfddf 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2617,21 +2617,21 @@ void CheckStl::useStlAlgorithm() if (!Token::Match(loopVar, "%var%")) continue; } - else if (Token::simpleMatch(splitTok, ";") && Token::simpleMatch(splitTok->astOperand2(), ";")) { // iterator-based loop - const Token* comp = splitTok->astOperand2()->astOperand1(); - loopVar = Token::Match(comp, "%comp%") ? comp->astOperand1() : nullptr; + 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; - const Token* init = splitTok->astOperand1(); - if (!Token::simpleMatch(init, "=") || !Token::Match(init->astOperand1(), "%varid%", loopVar->varId())) + if (!Token::simpleMatch(initTok, "=") || !Token::Match(initTok->astOperand1(), "%varid%", loopVar->varId())) continue; - const Token* inc = splitTok->astOperand2() ? splitTok->astOperand2()->astOperand2() : nullptr; - if (!inc || (!Token::Match(inc, "%op% %varid%", loopVar->varId()) && !Token::Match(inc->previous(), "%varid% %op%", loopVar->varId()))) + if (!Token::Match(stepTok, "%op% %varid%", loopVar->varId()) && !Token::Match(stepTok->previous(), "%varid% %op%", loopVar->varId())) continue; isIteratorLoop = true; } - else - continue; // Check for single assignment bool useLoopVarInAssign; From 51e6d24eb878f3aaa9c4d3cb7dfa7b33176f632f Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 11 Jun 2022 21:04:28 +0200 Subject: [PATCH 09/44] Only war for unary inc/dec --- lib/checkstl.cpp | 2 +- test/teststl.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index d6ff10e4083..1d03e57abf1 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2625,7 +2625,7 @@ void CheckStl::useStlAlgorithm() continue; if (!Token::simpleMatch(initTok, "=") || !Token::Match(initTok->astOperand1(), "%varid%", loopVar->varId())) continue; - if (!Token::Match(stepTok, "%op% %varid%", loopVar->varId()) && !Token::Match(stepTok->previous(), "%varid% %op%", loopVar->varId())) + if (!stepTok->isIncDecOp()) continue; isIteratorLoop = true; } diff --git a/test/teststl.cpp b/test/teststl.cpp index abf6181c5ab..f7231c7edf8 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4679,6 +4679,14 @@ class TestStl : public TestFixture { " return r;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("int f(const std::vector& 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() { From 29646eccfd81cbd4b7dc3078321c8f633d0d0022 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Jun 2022 15:31:38 +0200 Subject: [PATCH 10/44] Fix some useStlAlgorithm warnings --- cli/cppcheckexecutor.cpp | 8 +++---- lib/check.cpp | 14 ++++++------ lib/symboldatabase.cpp | 28 ++++++++++------------- lib/symboldatabase.h | 9 ++++---- lib/utils.h | 8 +++---- lib/valueflow.cpp | 49 ++++++++++++++++++---------------------- 6 files changed, 52 insertions(+), 64 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index af227c891a8..128d566cbe0 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #if !defined(NO_UNIX_SIGNAL_HANDLING) && defined(__GNUC__) && !defined(__MINGW32__) && !defined(__OS2__) #define USE_UNIX_SIGNAL_HANDLING @@ -925,10 +926,9 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) // Single process settings.jointSuppressionReport = true; - std::size_t totalfilesize = 0; - for (std::map::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), [](auto v, const auto& f) { + return v + f.second; + }); std::size_t processedsize = 0; unsigned int c = 0; diff --git a/lib/check.cpp b/lib/check.cpp index 7579152a1e1..c729007305a 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -34,13 +34,13 @@ Check::Check(const std::string &aname) : mTokenizer(nullptr), mSettings(nullptr), mErrorLogger(nullptr), mName(aname) { - for (std::list::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) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5e31c502498..f9694decfd4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3354,13 +3354,9 @@ bool Type::hasCircularDependencies(std::set* ancestors) const bool Type::findDependency(const Type* ancestor) const { - if (this==ancestor) - return true; - for (std::vector::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 @@ -5478,11 +5474,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; } //--------------------------------------------------------------------------- @@ -5542,10 +5537,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); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index c5eb887e70b..4c3f043a229 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1065,11 +1065,10 @@ class CPPCHECKLIB Scope { } 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 { diff --git a/lib/utils.h b/lib/utils.h index 21993d63799..a47f9615e4c 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -98,11 +98,9 @@ inline static bool isPrefixStringCharLiteral(const std::string &str, char q, con inline static bool isStringCharLiteral(const std::string &str, char q) { static const std::vector 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) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 51a3daf3a03..87746eddf9a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3294,10 +3294,11 @@ static std::vector 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)}}; } @@ -5105,16 +5106,17 @@ static void valueFlowForwardConst(Token* start, [&] { // Follow references std::vector 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()) { @@ -6640,11 +6642,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& 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) { @@ -6722,16 +6722,11 @@ bool productParams(const std::unordered_map>& v for (const auto& arg:args) { if (arg.empty()) continue; - bool skip = false; // Make sure all arguments are the same path - MathLib::bigint path = arg.begin()->second.path; - for (const auto& p:arg) { - if (p.second.path != path) { - skip = true; - break; - } - } - if (skip) + const MathLib::bigint path = arg.begin()->second.path; + if (std::any_of(arg.begin(), arg.end(), [&](const std::pair& p) { + return p.second.path != path; + })) continue; f(arg); } From bf783998a68bc8745791d019474e18316b08b4f1 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Jun 2022 16:05:39 +0200 Subject: [PATCH 11/44] Don't use auto --- cli/cppcheckexecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 128d566cbe0..3897e036724 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -926,7 +926,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) // Single process settings.jointSuppressionReport = true; - const std::size_t totalfilesize = std::accumulate(mFiles.begin(), mFiles.end(), std::size_t(0), [](auto v, const auto& f) { + const std::size_t totalfilesize = std::accumulate(mFiles.begin(), mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& f) { return v + f.second; }); From a3dde5c912711891e66b19d1b7ab9a027a1a2ae2 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Jun 2022 16:36:24 +0200 Subject: [PATCH 12/44] Format --- lib/symboldatabase.cpp | 6 +++--- lib/symboldatabase.h | 2 +- lib/valueflow.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 24d270c5495..7339c562f83 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5474,7 +5474,7 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const { auto it = std::find_if(scopeList.begin(), scopeList.end(), [&](const Scope& s) { return s.className == name; - }); + }); return it == scopeList.end() ? nullptr : &*it; } @@ -5536,8 +5536,8 @@ const Type* Scope::findType(const std::string & name) const Scope *Scope::findInNestedListRecursive(const std::string & name) { auto it = std::find_if(nestedList.begin(), nestedList.end(), [&](const Scope* s) { - return s->className == name; - }); + return s->className == name; + }); if (it != nestedList.end()) return *it; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index a0465369127..7bfca5ba691 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1067,7 +1067,7 @@ class CPPCHECKLIB Scope { const Enumerator * findEnumerator(const std::string & name) const { auto it = std::find_if(enumeratorList.begin(), enumeratorList.end(), [&](const Enumerator& i) { return i.name->str() == name; - }); + }); return it == enumeratorList.end() ? nullptr : &*it; } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 12b5adbd5f9..05616512dd1 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6841,8 +6841,8 @@ bool productParams(const std::unordered_map>& v // Make sure all arguments are the same path const MathLib::bigint path = arg.begin()->second.path; if (std::any_of(arg.begin(), arg.end(), [&](const std::pair& p) { - return p.second.path != path; - })) + return p.second.path != path; + })) continue; f(arg); } From 19e906c8cb0d31129fc7b413404614f1ff8e29d7 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Jun 2022 16:36:41 +0200 Subject: [PATCH 13/44] Enable useStlAlgorithm in selfcheck --- .travis_suppressions | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis_suppressions b/.travis_suppressions index be88bc1277a..4a7ff5816fe 100644 --- a/.travis_suppressions +++ b/.travis_suppressions @@ -5,7 +5,6 @@ bitwiseOnBoolean # temporary suppressions - fix the warnings! unusedPrivateFunction:test/test*.cpp -useStlAlgorithm simplifyUsing:lib/valueptr.h symbolDatabaseWarning:gui/temp/moc_*.cpp simplifyUsing:gui/temp/moc_*.cpp From 4d7033e8fec4e2b48228ff298239bc81e08dcef1 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Jun 2022 17:24:41 +0200 Subject: [PATCH 14/44] Use STL algo --- lib/preprocessor.cpp | 14 +++++++------- lib/tokenlist.cpp | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index b73d63a7be5..117ccf8b4fe 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -33,6 +33,7 @@ #include // back_inserter #include #include +#include #include @@ -111,10 +112,9 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std: if (!errmsg.empty()) bad->push_back(BadInlineSuppression(tok->location, 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; @@ -1019,9 +1019,9 @@ static const std::uint32_t crc32Table[] = { static void crc32(const std::string &data, uint32_t& crc) { - for (char c : data) { - crc = crc32Table[(crc ^ (unsigned char)c) & 0xFF] ^ (crc >> 8); - } + crc = std::accumulate(data.begin(), data.end(), crc, [](uint32_t v, char c) { + return crc32Table[(v ^ (unsigned char)c) & 0xFF] ^ (v >> 8); + }); } uint32_t Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index a74cb2ccee8..aee971fc7f6 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -451,8 +452,9 @@ void TokenList::createTokens(simplecpp::TokenList&& tokenList) } if (mSettings && mSettings->relativePaths) { - for (std::string & mFile : mFiles) - mFile = Path::getRelativePath(mFile, mSettings->basePaths); + std::transform(mFiles.begin(), mFiles.end(), mFiles.begin(), [&](const std::string& f) { + return Path::getRelativePath(f, mSettings->basePaths); + }); } Token::assignProgressValues(mTokensFrontBack.front); @@ -465,13 +467,12 @@ uint64_t TokenList::calculateChecksum() const uint64_t checksum = 0; for (const Token* tok = front(); tok; tok = tok->next()) { const uint32_t subchecksum1 = tok->flags() + tok->varId() + tok->tokType(); - uint32_t subchecksum2 = 0; - for (char i : tok->str()) - subchecksum2 += (uint32_t)i; - if (!tok->originalName().empty()) { - for (char i : tok->originalName()) - subchecksum2 += (uint32_t)i; - } + uint32_t subchecksum2 = std::accumulate(tok->str().begin(), tok->str().end(), uint32_t(0), [](uint32_t v, char c) { + return v + c; + }); + subchecksum2 = std::accumulate(tok->originalName().begin(), tok->originalName().end(), subchecksum2, [](uint32_t v, char c) { + return v + c; + }); checksum ^= ((static_cast(subchecksum1) << 32) | subchecksum2); From 3de404c5b9fde42bfdca9c169533487b5a6ab8b1 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 11:32:31 +0200 Subject: [PATCH 15/44] Format --- lib/preprocessor.cpp | 6 +++--- lib/valueflow.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 117ccf8b4fe..12f6378ab78 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1019,9 +1019,9 @@ static const std::uint32_t crc32Table[] = { static void crc32(const std::string &data, uint32_t& crc) { - crc = std::accumulate(data.begin(), data.end(), crc, [](uint32_t v, char c) { - return crc32Table[(v ^ (unsigned char)c) & 0xFF] ^ (v >> 8); - }); + crc = std::accumulate(data.begin(), data.end(), crc, [](uint32_t v, char c) { + return crc32Table[(v ^ (unsigned char)c) & 0xFF] ^ (v >> 8); + }); } uint32_t Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 05616512dd1..3836017a956 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6840,7 +6840,7 @@ bool productParams(const std::unordered_map>& v continue; // Make sure all arguments are the same path const MathLib::bigint path = arg.begin()->second.path; - if (std::any_of(arg.begin(), arg.end(), [&](const std::pair& p) { + if (std::any_of(arg.begin(), arg.end(), [&](const std::pair& p) { return p.second.path != path; })) continue; From 0c93bb0d52af198f271270435c1c4cd99593c3ae Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 11:51:14 +0200 Subject: [PATCH 16/44] Use STL algo --- cli/cppcheckexecutor.cpp | 19 +++++++------------ cli/threadexecutor.cpp | 9 ++++----- lib/tokenize.cpp | 20 +++++++------------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 3897e036724..854e7efc561 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -154,14 +154,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& 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; @@ -179,11 +175,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c // filter only for the selected filenames from all project files std::list newList; - for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) { - if (matchglobs(mSettings->fileFilters, fsetting.filename)) { - newList.emplace_back(fsetting); - } - } + const std::list& 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 { diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 134155d4103..edfb158097a 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef __SVR4 // Solaris #include @@ -57,7 +58,6 @@ using std::memset; #ifdef THREADING_MODEL_THREAD #include -#include #endif ThreadExecutor::ThreadExecutor(const std::map &files, Settings &settings, ErrorLogger &errorLogger) @@ -225,10 +225,9 @@ unsigned int ThreadExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - std::size_t totalfilesize = 0; - for (std::map::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i) { - totalfilesize += i->second; - } + const std::size_t totalfilesize = std::acumulate(mFiles.begin(); mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& p) { + return v + p.second; + }); std::list rpipes; std::map childFile; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bfe9e517893..575844745e3 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1852,11 +1852,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& c) { + return c.name == childName; + }); } const ScopeInfo3 * findInChildren(const std::string & scope) const { @@ -7992,16 +7990,12 @@ bool Tokenizer::simplifyKnownVariables() } } - for (auto constantVar = constantVars.rbegin(); constantVar != constantVars.rend(); constantVar++) { - bool referenceFound = false; + for (auto constantVar = constantVars.rbegin(); constantVar != constantVars.rend(); constantVar++) { std::list usageList = constantValueUsages[constantVar->first]; - for (Token* usage : usageList) { + const bool referenceFound = std::any_of(usageList.begin(), usageList.end(), [&](const Token* usage) { // check if any usages of each known variable are a reference - if (Token::Match(usage->tokAt(-2), "(|[|,|{|return|%op% & %varid%", constantVar->first)) { - referenceFound = true; - break; - } - } + return Token::Match(usage->tokAt(-2), "(|[|,|{|return|%op% & %varid%", constantVar->first); + }); if (!referenceFound) { // replace all usages of non-referenced known variables with their value From aa7abcac30403a8b12f19d0d5b0e6f5d44d817c3 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 12:04:54 +0200 Subject: [PATCH 17/44] Format --- lib/tokenize.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 575844745e3..f51c9a1badb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7990,11 +7990,11 @@ bool Tokenizer::simplifyKnownVariables() } } - for (auto constantVar = constantVars.rbegin(); constantVar != constantVars.rend(); constantVar++) { + for (auto constantVar = constantVars.rbegin(); constantVar != constantVars.rend(); constantVar++) { std::list usageList = constantValueUsages[constantVar->first]; const bool referenceFound = std::any_of(usageList.begin(), usageList.end(), [&](const Token* usage) { // check if any usages of each known variable are a reference - return Token::Match(usage->tokAt(-2), "(|[|,|{|return|%op% & %varid%", constantVar->first); + return Token::Match(usage->tokAt(-2), "(|[|,|{|return|%op% & %varid%", constantVar->first); }); if (!referenceFound) { From b979bd8f1f507c4a65bc85428c524b3bd76e0cab Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 12:06:40 +0200 Subject: [PATCH 18/44] Typo --- cli/threadexecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index edfb158097a..6be3b7a405d 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -225,7 +225,7 @@ unsigned int ThreadExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - const std::size_t totalfilesize = std::acumulate(mFiles.begin(); mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& p) { + const std::size_t totalfilesize = std::accumulate(mFiles.begin(); mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& p) { return v + p.second; }); From e2f60168396018ce32bfb6f640c939c340d42066 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 12:10:19 +0200 Subject: [PATCH 19/44] Typo --- cli/threadexecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 6be3b7a405d..3928c1b6574 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -225,7 +225,7 @@ unsigned int ThreadExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - const std::size_t totalfilesize = std::accumulate(mFiles.begin(); mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& p) { + const std::size_t totalfilesize = std::accumulate(mFiles.begin(), mFiles.end(), std::size_t(0), [](std::size_t v, const std::pair& p) { return v + p.second; }); From 45482468bf203a7a9acdb4ec8e6aacd4401139fc Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 16:08:30 +0200 Subject: [PATCH 20/44] Use STL algo --- gui/checkthread.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index d0a3a550a4f..8c4dff94b68 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -410,11 +410,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() From 6545ca666963f36c5fdd3f788a4163158665064d Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 19:32:27 +0200 Subject: [PATCH 21/44] Don't suggest std::accumulate for containers, where overloaded operators can be costly https://quick-bench.com/q/vkQFTHndSx1UyHHygwuZgJTNmdQ --- lib/checkstl.cpp | 2 ++ test/teststl.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index d2daf8409f9..92a1df121d3 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2634,6 +2634,8 @@ void CheckStl::useStlAlgorithm() bool useLoopVarInAssign; const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign); if (assignTok) { + if (astIsContainer(assignTok)) // don't warn for containers, where overloaded operators can be costly + continue; int assignVarId = assignTok->astOperand1()->varId(); std::string algo; if (assignVarId == loopVar->varId()) { diff --git a/test/teststl.cpp b/test/teststl.cpp index abf6181c5ab..63ca8c94850 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4679,6 +4679,14 @@ class TestStl : public TestFixture { " return r;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("std::string f(std::vector 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()); } void loopAlgoContainerInsert() { From 1083aef0e93a019d3117d60fd2f519b5d228e075 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 19:33:05 +0200 Subject: [PATCH 22/44] Fix compilation, use STL algo --- gui/checkthread.cpp | 2 +- test/testsuppressions.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 8c4dff94b68..2cda2ada3be 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -410,7 +410,7 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS bool CheckThread::isSuppressed(const Suppressions::ErrorMessage &errorMessage) const { - return std::any_of(mSuppressions.begin(), mSuppressions.end(), [](const Suppressions::Suppression& s) { + return std::any_of(mSuppressions.begin(), mSuppressions.end(), [&](const Suppressions::Suppression& s) { return s.isSuppressed(errorMessage); }); } diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 98ae2e29d69..e23218c9f09 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -36,6 +36,7 @@ #include #include #include +#include class TestSuppressions : public TestFixture { public: @@ -201,10 +202,10 @@ class TestSuppressions : public TestFixture { EXPECT_EQ("", r); } - unsigned int exitCode = 0; - for (std::map::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& f) { + return v | cppCheck.check(f.first, f.second); + }); + if (cppCheck.analyseWholeProgram()) exitCode |= settings.exitCode; From 1548aedc15b6e2c295b4711e4bfed4e0ee2c9f94 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 19:36:30 +0200 Subject: [PATCH 23/44] Format --- test/testsuppressions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index e23218c9f09..8300b347b5f 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -203,7 +203,7 @@ class TestSuppressions : public TestFixture { } unsigned int exitCode = std::accumulate(files.begin(), files.end(), 0U, [&](unsigned int v, const std::pair& f) { - return v | cppCheck.check(f.first, f.second); + return v | cppCheck.check(f.first, f.second); }); if (cppCheck.analyseWholeProgram()) From eab9ce68811df05bcab57bbd2d63605a81e9e7bd Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 20 Jun 2022 20:07:21 +0200 Subject: [PATCH 24/44] Use STL algo --- lib/importproject.cpp | 9 +++------ lib/library.cpp | 22 +++++++++------------- lib/mathlib.cpp | 9 ++++----- lib/symboldatabase.cpp | 9 ++++----- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 179e7e4fc6a..7c5159f09d4 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -762,12 +762,9 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map& argumentChecksFunc = functions.at(getFunctionName(ftok)).argumentChecks; - for (const std::pair & argCheckFunc : argumentChecksFunc) { - if (argCheckFunc.second.formatstr) { - return argCheckFunc.first - 1; - } - } - return -1; + auto it = std::find_if(argumentChecksFunc.begin(), argumentChecksFunc.end(), [](const std::pair& a) { + return a.second.formatstr; + }); + return it == argumentChecksFunc.end() ? -1 : it->first - 1; } bool Library::formatstr_scan(const Token* ftok) const @@ -1370,14 +1368,12 @@ bool Library::hasminsize(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return false; - const std::unordered_map::const_iterator it1 = functions.find(getFunctionName(ftok)); - if (it1 == functions.cend()) + const std::unordered_map::const_iterator it = functions.find(getFunctionName(ftok)); + if (it == functions.cend()) return false; - for (const std::pair & 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& a) { + return !a.second.minsizes.empty(); + }); } Library::ArgumentChecks::Direction Library::getArgDirection(const Token* ftok, int argnr) const diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 9784e03fac9..0b4377c82d1 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -341,11 +342,9 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str) unsigned int MathLib::encodeMultiChar(const std::string& str) { - unsigned int retval = 0; - for (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) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 7339c562f83..164c797dc84 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5553,11 +5553,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; } //--------------------------------------------------------------------------- From 960ca80dc5dd8b2ba5620754847674ad14c5aaea Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 20 Jun 2022 22:27:18 +0200 Subject: [PATCH 25/44] Use std::find_if --- lib/templatesimplifier.cpp | 54 ++++++++++++++++---------------------- lib/tokenize.cpp | 9 ++++--- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2bb695933dd..60500ac9821 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -3376,22 +3376,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(); } } } @@ -3402,22 +3397,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(); } } } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f51c9a1badb..9060a93af52 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1874,10 +1874,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& c) { + return &c != this && c.type == Record && (c.name == scope || c.fullName == scope); + }); + if (it != tempScope->children.end()) + return &*it; // check siblings for same name if (tempScope->parent) { for (const auto &sibling : tempScope->parent->children) { From 686a998f5695d86c49844a3cc4dac265fa8e7928 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 21 Jun 2022 18:55:23 +0200 Subject: [PATCH 26/44] Use STL algo --- gui/filelist.cpp | 6 +++--- lib/checkcondition.cpp | 10 +++------- lib/checkleakautovar.cpp | 8 +++----- lib/checksizeof.cpp | 8 +++++--- lib/tokenize.cpp | 9 +++++---- test/testtoken.cpp | 14 ++++++-------- 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/gui/filelist.cpp b/gui/filelist.cpp index b10ec3ddfe0..dd5fc26fd09 100644 --- a/gui/filelist.cpp +++ b/gui/filelist.cpp @@ -110,9 +110,9 @@ void FileList::addExcludeList(const QStringList &paths) static std::vector toStdStringList(const QStringList &stringList) { std::vector 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; } diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index cf082e1dc98..8b43b75127e 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -747,13 +747,9 @@ void CheckCondition::multiCondition2() // Incomplete code break; } - bool changed = false; - for (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; } diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 3ba2da1a569..e124f85c932 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -80,11 +80,9 @@ static bool isAutoDealloc(const Variable *var) static bool isVarTokComparison(const Token * tok, const Token ** vartok, const std::vector>& 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 auto& op) { + return astIsVariableComparison(tok, op.first, op.second, vartok); + }); } //--------------------------------------------------------------------------- diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 3c95a60ab21..ce14c21bdec 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -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(); } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f51c9a1badb..4bbfce8ec77 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2159,10 +2159,11 @@ namespace { if (tempScope->usingNamespaces.find(scope) != tempScope->usingNamespaces.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(tempScope->usingNamespaces.begin(), tempScope->usingNamespaces.end(), [&](const std::string& ns) { + return scope == ns + suffix; + })) + return true; } } tempScope = tempScope->parent; diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 66a24c34f6c..d19b736bd4e 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -741,10 +741,9 @@ class TestToken : public TestFixture { append_vector(test_ops, logicalOps); append_vector(test_ops, assignmentOps); - std::vector::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 other_ops; @@ -763,10 +762,9 @@ class TestToken : public TestFixture { append_vector(test_ops, comparisonOps); append_vector(test_ops, logicalOps); - std::vector::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 other_ops; From a9295c9fb44c91a1f30af1664a89f41f754b83ef Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 21 Jun 2022 19:24:16 +0200 Subject: [PATCH 27/44] Don't use auto --- lib/checkleakautovar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e124f85c932..0231f3a48dc 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -80,7 +80,7 @@ static bool isAutoDealloc(const Variable *var) static bool isVarTokComparison(const Token * tok, const Token ** vartok, const std::vector>& ops) { - return std::any_of(ops.begin(), ops.end(), [&](const auto& op) { + return std::any_of(ops.begin(), ops.end(), [&](const std::pair& op) { return astIsVariableComparison(tok, op.first, op.second, vartok); }); } From 4408aef9e6f97e198d5f9912fb7bb734b5e2220b Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 21 Jun 2022 20:39:21 +0200 Subject: [PATCH 28/44] Use STL algo --- lib/checkother.cpp | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 88431816b7c..0a799855c69 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -490,12 +490,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& 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) @@ -1212,11 +1210,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) @@ -3407,10 +3405,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); @@ -3435,16 +3435,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(it->nameToken(), it->nameToken(), "argument"); continue; + } } const Token *shadowed = findShadowed(scope.nestedIn, var.name(), var.nameToken()->linenr()); From 843c05cd9a574162d3fae79914b0a2621824c165 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 21 Jun 2022 20:40:25 +0200 Subject: [PATCH 29/44] Fix previous commit --- lib/checkother.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 0a799855c69..424010d0e57 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3440,7 +3440,7 @@ void CheckOther::checkShadowVariables() return arg.nameToken() && var.name() == arg.name(); }); if (it != argList.end()) { - shadowError(it->nameToken(), it->nameToken(), "argument"); + shadowError(var.nameToken(), it->nameToken(), "argument"); continue; } } From a4438c4980b08e9e198fb601ac5e1d6d093fbd4f Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Jun 2022 16:03:35 +0200 Subject: [PATCH 30/44] Use STL algo, format --- lib/checkclass.cpp | 70 +++++++++++++++---------------------- lib/checkother.cpp | 2 +- test/testsymboldatabase.cpp | 22 +++++------- test/testvalueflow.cpp | 68 +++++++++++++++++------------------ 4 files changed, 72 insertions(+), 90 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 99627e583a9..f1a324ecf51 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -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) @@ -149,17 +147,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) { @@ -329,13 +323,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. @@ -609,8 +599,9 @@ bool CheckClass::canNotMove(const Scope *scope) static void getAllVariableMembers(const Scope *scope, std::vector& 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) @@ -677,10 +668,11 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope) if (derivedFrom && derivedFrom->classScope) { const std::list& 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; } @@ -782,13 +774,11 @@ void CheckClass::initializeVarList(const Function &func, std::listnext(), "%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); } @@ -1807,12 +1797,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; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 424010d0e57..dcb9dac6970 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3410,7 +3410,7 @@ static const Token *findShadowed(const Scope *scope, const std::string &varname, }); if (it != scope->functionList.end()) return it->tokenDef; - + if (scope->type == Scope::eLambda) return nullptr; const Token* shadowed = findShadowed(scope->nestedIn, varname, linenr); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 4030da2c152..1b1b54faf39 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2607,13 +2607,10 @@ class TestSymbolDatabase : public TestFixture { "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) @@ -2641,13 +2638,10 @@ class TestSymbolDatabase : public TestFixture { "}"); // 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) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 3d48a01fd38..7787202e00d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -301,10 +301,10 @@ class TestValueFlow : public TestFixture { 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; } } @@ -320,11 +320,10 @@ class TestValueFlow : public TestFixture { 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; } } @@ -339,11 +338,10 @@ class TestValueFlow : public TestFixture { 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; } } @@ -381,12 +379,13 @@ class TestValueFlow : public TestFixture { 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; } } @@ -400,12 +399,13 @@ class TestValueFlow : public TestFixture { 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; } } @@ -420,10 +420,10 @@ class TestValueFlow : public TestFixture { 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; } } @@ -438,10 +438,10 @@ class TestValueFlow : public TestFixture { 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; } } @@ -457,10 +457,10 @@ class TestValueFlow : public TestFixture { 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; } } From 6a2b6ff2f598259fb74677b02aa2886aa0e38faf Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Jun 2022 16:21:50 +0200 Subject: [PATCH 31/44] Format --- lib/checkclass.cpp | 8 ++++---- test/testsymboldatabase.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index f1a324ecf51..17e9a339f5f 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1797,10 +1797,10 @@ void CheckClass::virtualDestructor() if (printInconclusive) { const Function *destructor = scope->getDestructor(); if (destructor && !destructor->hasVirtualSpecifier() && destructor->access == AccessControl::Public) { - if (std::any_of(scope->functionList.begin(), scope->functionList.end(), [](const Function& func) { - return func.hasVirtualSpecifier(); - })) - inconclusiveErrors.push_back(destructor); + if (std::any_of(scope->functionList.begin(), scope->functionList.end(), [](const Function& func) { + return func.hasVirtualSpecifier(); + })) + inconclusiveErrors.push_back(destructor); } } continue; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 1b1b54faf39..3367329e92a 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2639,8 +2639,8 @@ class TestSymbolDatabase : public TestFixture { // Locate the scope for the class.. auto it = std::find_if(db->scopeList.begin(), db->scopeList.end(), [](const Scope& s) { - return s.isClassOrStruct(); - }); + return s.isClassOrStruct(); + }); const Scope* scope = (it == db->scopeList.end()) ? nullptr : &*it; ASSERT(scope != nullptr); From 7e2f452d33d5248ab32c21f2b77bdbdeffff3e89 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Jun 2022 17:16:08 +0200 Subject: [PATCH 32/44] Use STL algo, format --- test/testsymboldatabase.cpp | 36 ++++++++++++++++++------------------ test/testvalueflow.cpp | 9 ++++----- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 3367329e92a..7061f47eaa7 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -108,10 +108,11 @@ class TestSymbolDatabase : public TestFixture { 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; @@ -2923,12 +2924,11 @@ class TestSymbolDatabase : public TestFixture { // Global scope, Fred, Fred::Fred, Fred::~Fred 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; - } + // Find the scope for the Fred struct.. + 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 @@ -2937,11 +2937,11 @@ class TestSymbolDatabase : public TestFixture { // 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.. @@ -5007,9 +5007,9 @@ class TestSymbolDatabase : public TestFixture { 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 auto& scope) { + return scope.varlist.empty(); + })); } void createSymbolDatabaseFindAllScopes4() diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7787202e00d..f60529d7cc3 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4531,11 +4531,10 @@ class TestValueFlow : public TestFixture { } 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() { From 469e359c11c2ffc699048241a1ee5226a6be16d2 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Jun 2022 17:34:56 +0200 Subject: [PATCH 33/44] Don't use auto, format --- test/testsymboldatabase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 7061f47eaa7..d92e98d0ae9 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2924,7 +2924,7 @@ class TestSymbolDatabase : public TestFixture { // Global scope, Fred, Fred::Fred, Fred::~Fred ASSERT_EQUALS(4U, db->scopeList.size()); - // Find the scope for the Fred struct.. + // Find the scope for the Fred struct.. auto it = std::find_if(db->scopeList.begin(), db->scopeList.end(), [&](const Scope& scope) { return scope.isClassOrStruct() && scope.className == "Fred"; }); @@ -5007,7 +5007,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(1, db->scopeList.front().varlist.size()); auto list = db->scopeList; list.pop_front(); - ASSERT_EQUALS(true, std::all_of(list.begin(), list.end(), [](const auto& scope) { + ASSERT_EQUALS(true, std::all_of(list.begin(), list.end(), [](const Scope& scope) { return scope.varlist.empty(); })); } From b98bfd1ee3172a1ac221eb2f2290545d8bf8bda6 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Jun 2022 18:31:13 +0200 Subject: [PATCH 34/44] Use STL algo --- lib/templatesimplifier.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 60500ac9821..dcaf0b8859c 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -727,12 +727,9 @@ static bool areAllParamsTypes(const std::vector ¶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() @@ -1771,15 +1768,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, "", 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 From 712a637a6dd6c971fdd2e280c32d52a1aec48080 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Wed, 22 Jun 2022 23:12:14 +0200 Subject: [PATCH 35/44] Use STL algo --- lib/checkautovariables.cpp | 8 ++--- lib/checkclass.cpp | 10 ++---- lib/checkunusedvar.cpp | 62 +++++++++++++++----------------------- 3 files changed, 31 insertions(+), 49 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index e85796d6123..0158e63503a 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -411,10 +411,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; } diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 17e9a339f5f..705eb7b8197 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -185,13 +185,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; } diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 0b30b03762c..971ff23f674 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -774,12 +774,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; @@ -1414,13 +1413,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; } @@ -1434,17 +1430,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; - } - } - } - } + 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; @@ -1578,10 +1569,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) { @@ -1627,18 +1618,13 @@ bool CheckUnusedVar::isEmptyType(const Type* type) if (type && type->classScope && type->classScope->numConstructors == 0 && (type->classScope->varlist.empty())) { - for (std::vector::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, From d1bc779f43e3fe3871d15b5350521a92c67dcf42 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 23 Jun 2022 12:54:07 +0200 Subject: [PATCH 36/44] Use STL algo --- gui/main.cpp | 12 +++++++----- lib/token.cpp | 27 ++++++++++++--------------- lib/tokenize.cpp | 16 +++++++--------- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/gui/main.cpp b/gui/main.cpp index c1605796085..cd3e1987843 100644 --- a/gui/main.cpp +++ b/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); diff --git a/lib/token.cpp b/lib/token.cpp index da8e0940df0..8056113657a 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1654,24 +1654,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 << " mImpl->mValues << "\">" << std::endl; + out << " " << std::endl; else if (line != tok->linenr()) out << "Line " << tok->linenr() << std::endl; line = tok->linenr(); if (!xml) { - 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) { @@ -1687,10 +1684,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 << " mImpl->mValues->front()) + if (&value != &values->front()) out << ","; out << value.toString(); } } if (xml) out << " " << std::endl; - else if (tok->mImpl->mValues->size() > 1U) + else if (values->size() > 1U) out << '}' << std::endl; else out << std::endl; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b4fcdb1b060..c9f9eb50002 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -12480,13 +12480,11 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const { if (!mPreprocessor) return false; - for (const Directive &d: mPreprocessor->getDirectives()) { - if (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()]) - 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()]; + }); } From 90e67f7a82da9120808a393fc175d954dfaa3091 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 23 Jun 2022 20:17:07 +0200 Subject: [PATCH 37/44] Use STL algo, format, fix FP with container --- gui/mainwindow.cpp | 12 +++++++----- lib/checkstl.cpp | 4 +++- lib/clangimport.cpp | 27 +++++++++++++-------------- lib/tokenize.cpp | 8 ++++---- test/teststl.cpp | 9 +++++++++ 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index ec52843ff67..bcc745218ec 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -430,9 +430,10 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons mIsLogfileLoaded = false; if (mProjectFile) { std::vector 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()) { @@ -533,8 +534,9 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar if (!checkSettings.buildDir.empty()) { checkSettings.loadSummaries(); std::list 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); } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 2b490b3d21d..2329cdf3a5c 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2634,7 +2634,7 @@ void CheckStl::useStlAlgorithm() bool useLoopVarInAssign; const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign); if (assignTok) { - if (astIsContainer(assignTok)) // don't warn for containers, where overloaded operators can be costly + if (astIsContainer(assignTok->astOperand1())) // don't warn for containers, where overloaded operators can be costly continue; int assignVarId = assignTok->astOperand1()->varId(); std::string algo; @@ -2700,6 +2700,8 @@ void CheckStl::useStlAlgorithm() // Check for single assign assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign); if (assignTok) { + if (astIsContainer(assignTok->astOperand1())) // don't warn for containers, where overloaded operators can be costly + continue; const int assignVarId = assignTok->astOperand1()->varId(); std::string algo; if (assignVarId == loopVar->varId()) { diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 5be38e6f04f..462efec3015 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -41,6 +41,7 @@ #include #include #include +#include static const std::string AccessSpecDecl = "AccessSpecDecl"; static const std::string ArraySubscriptExpr = "ArraySubscriptExpr"; @@ -1441,16 +1442,15 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList) // definition if (isDefinition()) { std::vector 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); @@ -1525,10 +1525,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); } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c9f9eb50002..2a5531d6736 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -12482,9 +12482,9 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const 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()]; + d.linenr >= start->linenr() && + d.linenr <= end->linenr() && + start->fileIndex() < list.getFiles().size() && + d.file == list.getFiles()[start->fileIndex()]; }); } diff --git a/test/teststl.cpp b/test/teststl.cpp index f638834862c..5a71cf7cc38 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4688,6 +4688,15 @@ class TestStl : public TestFixture { "}\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& v) {\n" " int sum = 0;\n" " for (auto it = v.begin(); it != v.end(); it += 2)\n" From 8a4d2883e45f995f005adf8641f594d4dd7fe999 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 23 Jun 2022 23:51:56 +0200 Subject: [PATCH 38/44] Use std::transform, don't suggest std::accumulate for bool --- cli/cmdlineparser.cpp | 4 ++-- gui/checkthread.cpp | 6 +++--- lib/checkclass.cpp | 15 +++++++++------ lib/checkstl.cpp | 2 ++ lib/tokenize.cpp | 5 +++-- test/teststl.cpp | 8 ++++---- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 69af1c4ec8f..2781ad8bf2e 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -609,8 +609,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); diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 2cda2ada3be..24791bfd696 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -397,9 +397,9 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS continue; std::list 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(); diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 705eb7b8197..9f32b49c985 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -615,8 +615,9 @@ std::vector CheckClass::createUsageList(const Scope *scope) std::vector 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; } @@ -2626,9 +2627,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"; @@ -2660,8 +2662,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"; diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 2329cdf3a5c..5a7bb868675 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2636,6 +2636,8 @@ void CheckStl::useStlAlgorithm() if (assignTok) { if (astIsContainer(assignTok->astOperand1())) // don't warn for containers, where overloaded operators can be costly continue; + if (astIsBool(assignTok->astOperand1())) // std::accumulate is not a good fit for bool values, std::all/any/none_of return early + continue; int assignVarId = assignTok->astOperand1()->varId(); std::string algo; if (assignVarId == loopVar->varId()) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2a5531d6736..2bca1ed16c1 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4397,8 +4397,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* it) { + return ScopeInfo2(it->str(), tokStart->link()); + }); for (Token *tok2 = tokStart->next(); tok2 && tok2 != tokStart->link(); tok2 = tok2->next()) { // skip parentheses.. diff --git a/test/teststl.cpp b/test/teststl.cpp index 5a71cf7cc38..dd8d7841ec8 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4611,7 +4611,7 @@ class TestStl : public TestFixture { " 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" @@ -4620,7 +4620,7 @@ class TestStl : public TestFixture { " 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" @@ -4629,7 +4629,7 @@ class TestStl : public TestFixture { " 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" @@ -4638,7 +4638,7 @@ class TestStl : public TestFixture { " 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" From a1be1a0c390a5fc1472243632e6d4b7e49880839 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 24 Jun 2022 00:01:45 +0200 Subject: [PATCH 39/44] Fix build --- gui/checkthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 24791bfd696..7697de4a513 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -398,7 +398,7 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS std::list callstack; 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) + 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(); From e94a925993f9e107a434f9e3050dcda72f4a84da Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 9 Jul 2022 18:28:33 +0200 Subject: [PATCH 40/44] Restore Use STL algo fixes --- cli/processexecutor.cpp | 7 +++--- cli/threadexecutor.cpp | 13 ++++++----- lib/preprocessor.cpp | 7 +++--- lib/tokenize.cpp | 52 ++++++++++++++++++++--------------------- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index a248e078d9c..51b312aade0 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -216,10 +216,9 @@ unsigned int ProcessExecutor::check() unsigned int fileCount = 0; unsigned int result = 0; - std::size_t totalfilesize = 0; - for (std::map::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& p) { + return v + p.second; + }); std::list rpipes; std::map childFile; diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index ab577745014..232201529d4 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -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& files = mThreadExecutor.mFiles; + mItNextFile = files.begin(); mItNextFileSettings = mThreadExecutor.mSettings.project.fileSettings.begin(); - mTotalFiles = mThreadExecutor.mFiles.size() + mThreadExecutor.mSettings.project.fileSettings.size(); - for (std::map::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& p) { + return v + p.second; + }); } void reportOut(const std::string &outmsg, Color c) override diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 148932380ea..b33795faca0 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -112,10 +112,9 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std: if (!errmsg.empty()) bad->push_back(BadInlineSuppression(tok->location, 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; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 406cc766abf..e63a9b1b7fa 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1865,11 +1865,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 { @@ -1889,10 +1887,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) { @@ -2169,15 +2168,17 @@ namespace { const ScopeInfo3 * tempScope = scopeInfo; while (tempScope) { //if (!tempScope->parent->usingNamespaces.empty()) { - if (!tempScope->usingNamespaces.empty()) { + const std::set& 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; @@ -4410,8 +4411,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.. @@ -10049,13 +10051,11 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const { if (!mPreprocessor) return false; - for (const Directive &d: mPreprocessor->getDirectives()) { - if (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()]) - 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()]; + }); } From be8c9ec0f4262d8b677773b3da6e4b3017afab2e Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 9 Jul 2022 20:08:32 +0200 Subject: [PATCH 41/44] Format --- lib/tokenize.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index e63a9b1b7fa..6d2f84d250a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10053,9 +10053,9 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const 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()]; + d.linenr >= start->linenr() && + d.linenr <= end->linenr() && + start->fileIndex() < list.getFiles().size() && + d.file == list.getFiles()[start->fileIndex()]; }); } From e9b36ff1bf8369d9e6bf2ca217beb5e71799cb27 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 9 Jul 2022 20:10:21 +0200 Subject: [PATCH 42/44] Missing include --- cli/processexecutor.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 51b312aade0..d47d105e9f5 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -35,14 +35,17 @@ #include #include #include -#include #include #include #include +#include +#include + #include #include #include -#include +#include + #ifdef __SVR4 // Solaris #include From 5233db322bd32d7355c80cb81ec59c637846647d Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 10 Oct 2022 12:17:32 +0200 Subject: [PATCH 43/44] Fix merge --- lib/checkstl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 48dfb93ed50..ecf7de109f6 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2803,6 +2803,8 @@ void CheckStl::useStlAlgorithm() if (assignTok) { if (astIsContainer(assignTok->astOperand1())) // don't warn for containers, where overloaded operators can be costly continue; + if (astIsBool(assignTok->astOperand1())) // std::accumulate is not a good fit for bool values, std::all/any/none_of return early + continue; const int assignVarId = assignTok->astOperand1()->varId(); std::string algo; if (assignVarId == loopVar->varId()) { From 192d0b94c5ba5a61f0e10cc6929f121af874305d Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 10 Oct 2022 12:50:49 +0200 Subject: [PATCH 44/44] Fix/streamline test cases --- lib/checkstl.cpp | 13 ++++++++++--- test/teststl.cpp | 6 +++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index ecf7de109f6..4b008348c7a 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -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 @@ -2737,6 +2744,8 @@ void CheckStl::useStlAlgorithm() 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()) { @@ -2801,9 +2810,7 @@ void CheckStl::useStlAlgorithm() // Check for single assign assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign); if (assignTok) { - if (astIsContainer(assignTok->astOperand1())) // don't warn for containers, where overloaded operators can be costly - continue; - if (astIsBool(assignTok->astOperand1())) // std::accumulate is not a good fit for bool values, std::all/any/none_of return early + if (!checkAssignee(assignTok->astOperand1())) continue; const int assignVarId = assignTok->astOperand1()->varId(); std::string algo; diff --git a/test/teststl.cpp b/test/teststl.cpp index ef700c5026c..88a5b3aca48 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -5097,7 +5097,7 @@ class TestStl : public TestFixture { " 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" @@ -5110,7 +5110,7 @@ class TestStl : public TestFixture { " 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" @@ -5123,7 +5123,7 @@ class TestStl : public TestFixture { " 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"