Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 10 additions & 3 deletions clang-tidy.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Does not improve the readability.
`misc-unconventional-assign-operator`<br/>
`bugprone-throwing-static-initialization`<br/>
`bugprone-command-processor`<br/>
`modernize-use-nodiscard`<br/>

To be evaluated (need to remove exclusion).

Expand All @@ -150,10 +151,16 @@ To be evaluated (need to remove exclusion).
To be evaluated (need to enable explicitly).

`modernize-type-traits`<br/>
`modernize-use-nodiscard`<br/>
`modernize-use-scoped-lock`<br/>

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`<br/>
`modernize-use-starts-ends-with`<br/>
`modernize-avoid-bind`<br/>
`modernize-make-unique`<br/>
`modernize-use-ranges`<br/>
`readability-container-contains`<br/>
`modernize-use-integer-sign-comparison`<br/>

These require us to default to a later standard than C++11 so we cannot apply them.

`portability-avoid-pragma-once`<br/>

Expand Down
5 changes: 3 additions & 2 deletions cmake/clang_tidy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lib/checkstl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 Function*, StrArg>::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;

Expand Down
6 changes: 3 additions & 3 deletions lib/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set<std::string>
{
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<std::string>::iterator it2 = ret.find(config2);
const auto it2 = utils::as_const(ret).find(config2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the point of making it const? I find it a little weird to create the iterator for the const object and then comparing it to the end iterator of the non-const object. this is invalid if as_const would return a constant copy so it depends on a implementation detail..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the point of making it const?

So we get a const_iterator. Before it was mutable which was unnecessary. I added the constness. Unfortunately there is no cfind() and the result depends on the object.

I find it a little weird to create the iterator for the const object and then comparing it to the end iterator of the non-const object.

It is the same object. iterator and const_iterator can be compared which each other so end() and cend() are interchangeable. I have some local changes cleaning this up and also thought about filing tickets to detect such inconsistencies-

this is invalid if as_const would return a constant copy so it depends on a implementation detail..

It is not a copy - it is a cast.

Copy link
Owner

@danmar danmar Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a copy - it is a cast.

I know. I said "if .. would return ..".

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
Expand Down Expand Up @@ -693,8 +693,8 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set<std::string>
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<std::string>::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);
}
Expand Down
16 changes: 8 additions & 8 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string, const Function*>::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;
Expand Down Expand Up @@ -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<std::string, const Function*>::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;
Expand Down Expand Up @@ -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<std::string, const Function*>::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;
Expand Down Expand Up @@ -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<std::string, const Function*>::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<Function *>(it->second);
if (destructor && func->type != FunctionType::eDestructor)
continue;
Expand Down
Loading