diff --git a/.clang-tidy b/.clang-tidy
index 8c30f2c602b..4b97d5f1404 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -43,15 +43,21 @@ Checks: >
-modernize-deprecated-ios-base-aliases,
-misc-include-cleaner,
-misc-unused-using-decls,
+ -modernize-avoid-bind,
+ -modernize-use-integer-sign-comparison,
-modernize-loop-convert,
-modernize-macro-to-enum,
+ -modernize-make-unique,
-modernize-raw-string-literal,
-modernize-replace-auto-ptr,
-modernize-return-braced-init-list,
-modernize-type-traits,
+ -modernize-use-constraints,
-modernize-use-designated-initializers,
-modernize-use-nodiscard,
+ -modernize-use-ranges,
-modernize-use-scoped-lock,
+ -modernize-use-starts-ends-with,
-modernize-use-trailing-return-type,
-performance-avoid-endl,
-performance-inefficient-string-concatenation,
@@ -61,6 +67,7 @@ Checks: >
-portability-std-allocator-const,
-readability-avoid-nested-conditional-operator,
-readability-braces-around-statements,
+ -readability-container-contains,
-readability-container-data-pointer,
-readability-enum-initial-value,
-readability-function-cognitive-complexity,
diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml
index 66528e96e52..a2f338a508f 100644
--- a/.github/workflows/clang-tidy.yml
+++ b/.github/workflows/clang-tidy.yml
@@ -61,7 +61,7 @@ jobs:
- name: Prepare CMake
run: |
- cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DWARNINGS_ARE_ERRORS=On
+ cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=20 -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DWARNINGS_ARE_ERRORS=On
env:
CC: clang-22
CXX: clang++-22
diff --git a/clang-tidy.md b/clang-tidy.md
index aae6918e372..8db32a4d7b0 100644
--- a/clang-tidy.md
+++ b/clang-tidy.md
@@ -133,6 +133,7 @@ Does not improve the readability.
`misc-unconventional-assign-operator`
`bugprone-throwing-static-initialization`
`bugprone-command-processor`
+`modernize-use-nodiscard`
To be evaluated (need to remove exclusion).
@@ -150,10 +151,16 @@ To be evaluated (need to remove exclusion).
To be evaluated (need to enable explicitly).
`modernize-type-traits`
-`modernize-use-nodiscard`
`modernize-use-scoped-lock`
-
-These apply to codebases which use later standards then C++11 (C++17 is used when building with Qt6) so we cannot simply apply them.
+`modernize-use-constraints`
+`modernize-use-starts-ends-with`
+`modernize-avoid-bind`
+`modernize-make-unique`
+`modernize-use-ranges`
+`readability-container-contains`
+`modernize-use-integer-sign-comparison`
+
+These require us to default to a later standard than C++11 so we cannot apply them.
`portability-avoid-pragma-once`
diff --git a/cmake/clang_tidy.cmake b/cmake/clang_tidy.cmake
index fe0efbbe32f..9bf68063489 100644
--- a/cmake/clang_tidy.cmake
+++ b/cmake/clang_tidy.cmake
@@ -25,8 +25,9 @@ if(RUN_CLANG_TIDY_NAMES)
endif()
message(STATUS "NPROC=${NPROC}")
- # TODO: introduced in run-clang-tidy-22
- set(CLANG_TIDY_CONFIG "-enable-check-profile")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 22)
+ set(CLANG_TIDY_CONFIG "-enable-check-profile")
+ endif()
# most of these are disabled because they are too noisy in our code
# clang-analyzer-core.CallAndMessage
diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp
index c4827157988..01bd9999e53 100644
--- a/lib/checkstl.cpp
+++ b/lib/checkstl.cpp
@@ -2039,8 +2039,8 @@ void CheckStl::string_c_str()
string_c_strAssignment(tok, tok->variable()->getTypeName());
}
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && tok->str() != scope.className) {
- const auto range = c_strFuncParam.equal_range(tok->function());
- for (std::multimap::const_iterator i = range.first; i != range.second; ++i) {
+ const auto range = utils::as_const(c_strFuncParam).equal_range(tok->function());
+ for (auto i = range.first; i != range.second; ++i) {
if (i->second.n == 0)
continue;
diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp
index a028fc5b864..6ca1515168e 100644
--- a/lib/preprocessor.cpp
+++ b/lib/preprocessor.cpp
@@ -643,7 +643,7 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set
{
const std::string::size_type eq = config.find('=');
const std::string config2 = (eq != std::string::npos) ? config.substr(0, eq) : config + "=" + config;
- const std::set::iterator it2 = ret.find(config2);
+ const auto it2 = utils::as_const(ret).find(config2);
if (it2 != ret.end()) {
if (eq == std::string::npos) {
// The instance in ret is more specific than the one in config (no =value), replace it with the one in config
@@ -693,8 +693,8 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set
const std::string &confCandidate = configs_ifndef.back();
if (ret.find(confCandidate) == ret.end()) {
// No instance of config_ifndef in ret. Check if a more specific version exists, in that case replace it
- const std::set::iterator it = ret.find(confCandidate + "=" + confCandidate);
- if (it != ret.end()) {
+ const auto it = utils::as_const(ret).find(confCandidate + "=" + confCandidate);
+ if (it != ret.cend()) {
// The instance in ret is more specific than the one in confCandidate (no =value), replace it with the one in confCandidate
ret.erase(it);
}
diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp
index c997a907501..0d4458fdb85 100644
--- a/lib/symboldatabase.cpp
+++ b/lib/symboldatabase.cpp
@@ -720,8 +720,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
}
bool newFunc = true; // Is this function already in the database?
- auto range = scope->functionMap.equal_range(tok->str());
- for (std::multimap::const_iterator it = range.first; it != range.second; ++it) {
+ auto range = utils::as_const(scope->functionMap).equal_range(tok->str());
+ for (auto it = range.first; it != range.second; ++it) {
if (it->second->argsMatch(scope, it->second->argDef, argStart, "", 0)) {
newFunc = false;
break;
@@ -804,8 +804,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
if (isFunction(ftok, scope, funcStart, argStart, declEnd)) {
if (declEnd && declEnd->str() == ";") {
bool newFunc = true; // Is this function already in the database?
- auto range = scope->functionMap.equal_range(ftok->str());
- for (std::multimap::const_iterator it = range.first; it != range.second; ++it) {
+ auto range = utils::as_const(scope->functionMap).equal_range(ftok->str());
+ for (auto it = range.first; it != range.second; ++it) {
if (it->second->argsMatch(scope, it->second->argDef, argStart, "", 0)) {
newFunc = false;
break;
@@ -3448,8 +3448,8 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
Function* function = nullptr;
// Lambda functions are always unique
if (tok->str() != "[") {
- auto range = scope->functionMap.equal_range(tok->str());
- for (std::multimap::const_iterator it = range.first; it != range.second; ++it) {
+ auto range = utils::as_const(scope->functionMap).equal_range(tok->str());
+ for (auto it = range.first; it != range.second; ++it) {
const Function *f = it->second;
if (f->hasBody())
continue;
@@ -3608,8 +3608,8 @@ void SymbolDatabase::addClassFunction(Scope *&scope, const Token *&tok, const To
}
if (match) {
- auto range = scope1->functionMap.equal_range(tok->str());
- for (std::multimap::const_iterator it = range.first; it != range.second; ++it) {
+ auto range = utils::as_const(scope1->functionMap).equal_range(tok->str());
+ for (auto it = range.first; it != range.second; ++it) {
auto * func = const_cast(it->second);
if (destructor && func->type != FunctionType::eDestructor)
continue;