From 1003b996ef37c9d83e9fd60bf560c61bd9c8224f Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 14 Mar 2026 22:17:25 +0100 Subject: [PATCH 01/11] clang-tidy.yml: updated to Clang 23 --- .github/workflows/clang-tidy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 333672d7..932a0d72 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -33,19 +33,19 @@ jobs: run: | wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 22 - sudo apt-get install clang-tidy-22 + sudo ./llvm.sh 23 + sudo apt-get install clang-tidy-23 - name: Verify clang-tidy configuration run: | - clang-tidy-22 --verify-config + clang-tidy-23 --verify-config - name: Prepare CMake run: | cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=23 -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_EXPORT_COMPILE_COMMANDS=ON env: - CXX: clang-22 + CXX: clang-23 - name: Clang-Tidy run: | - run-clang-tidy-22 -q -j $(nproc) -enable-check-profile -p=cmake.output + run-clang-tidy-23 -q -j $(nproc) -enable-check-profile -p=cmake.output From 2aafb551e8f504fe830bc5f910aa2728e7ac3ad4 Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 31 May 2026 21:06:45 +0200 Subject: [PATCH 02/11] .clang-tidy: removed disabling of `hicpp-*` checks as they no longer exist --- .clang-tidy | 1 - 1 file changed, 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index e0b384bf..215aa332 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -10,7 +10,6 @@ Checks: > -cppcoreguidelines-*, -fuchsia-*, -google-*, - -hicpp-*, -linuxkernel-*, -llvm-*, -llvmlibc-*, From 2c431d30f12631588190e863e4a33eaba8333bad Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 14 Mar 2026 22:22:10 +0100 Subject: [PATCH 03/11] .clang-tidy: disabled `readability-trailing-comma` clang-tidy check --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index 215aa332..277a440c 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -41,6 +41,7 @@ Checks: > -readability-isolate-declaration, -readability-magic-numbers, -readability-redundant-inline-specifier, + -readability-trailing-comma, -readability-use-concise-preprocessor-directives, -readability-uppercase-literal-suffix, -performance-avoid-endl, From 75d122b9cdf337bd2dc2173dd25dc7c5d4031286 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 11 May 2026 15:33:58 +0200 Subject: [PATCH 04/11] mitigated `bugprone-unhandled-code-paths` clang-tidy warnings --- main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/main.cpp b/main.cpp index 06afcfbb..190c95c9 100644 --- a/main.cpp +++ b/main.cpp @@ -49,6 +49,7 @@ int main(int argc, char **argv) if (*arg == '-') { bool found = false; const char c = arg[1]; + // NOLINTNEXTLINE(bugprone-unhandled-code-paths) switch (c) { case 'D': { // define symbol found = true; From 48f5b23b94486f1e9a4e6cc50d30eaa60dbcc581 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 16 Apr 2026 13:56:33 +0200 Subject: [PATCH 05/11] .clang-tidy: disabled `bugprone-signed-bitwise` for now --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index 277a440c..d53c263d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -20,6 +20,7 @@ Checks: > -bugprone-branch-clone, -bugprone-easily-swappable-parameters, -bugprone-narrowing-conversions, + -bugprone-signed-bitwise, -bugprone-switch-missing-default-case, -bugprone-throwing-static-initialization, -bugprone-unchecked-string-to-number-conversion, From e4e70c538660c8da05186e3790fee255e3d2ed31 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 16 Apr 2026 14:03:06 +0200 Subject: [PATCH 06/11] .clang-tidy: disabled `bugprone-std-exception-baseclass` for now --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index d53c263d..a35732c0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -21,6 +21,7 @@ Checks: > -bugprone-easily-swappable-parameters, -bugprone-narrowing-conversions, -bugprone-signed-bitwise, + -bugprone-std-exception-baseclass, -bugprone-switch-missing-default-case, -bugprone-throwing-static-initialization, -bugprone-unchecked-string-to-number-conversion, From 8d84600662c8dbf433b6cf86d81c70e859a3f163 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 14 Mar 2026 22:21:41 +0100 Subject: [PATCH 07/11] mitigated `misc-const-correctness` clang-tidy warnings --- main.cpp | 2 +- simplecpp.cpp | 24 ++++++++++++------------ test.cpp | 22 +++++++++++----------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/main.cpp b/main.cpp index 190c95c9..5bd9e9f3 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,7 @@ static bool isDir(const std::string& path) return (file_stat.st_mode & S_IFMT) == S_IFDIR; } -int main(int argc, char **argv) +int main(int argc, char *argv[]) { bool error = false; const char *filename = nullptr; diff --git a/simplecpp.cpp b/simplecpp.cpp index 748ea6a9..2f6788d8 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -153,12 +153,12 @@ static bool endsWith(const std::string &s, const std::string &e) return (s.size() >= e.size()) && std::equal(e.rbegin(), e.rend(), s.rbegin()); } -static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2) +static bool sameline(const simplecpp::Token * const tok1, const simplecpp::Token * const tok2) { return tok1 && tok2 && tok1->location.sameline(tok2->location); } -static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string &alt) +static bool isAlternativeBinaryOp(const simplecpp::Token * const tok, const std::string &alt) { return (tok->name && tok->str() == alt && @@ -168,7 +168,7 @@ static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string (tok->next->number || tok->next->name || tok->next->op == '(')); } -static bool isAlternativeUnaryOp(const simplecpp::Token *tok, const std::string &alt) +static bool isAlternativeUnaryOp(const simplecpp::Token * const tok, const std::string &alt) { return ((tok->name && tok->str() == alt) && (!tok->previous || tok->previous->op == '(') && @@ -622,7 +622,7 @@ static std::string escapeString(const std::string &str) return ostr.str(); } -static void portabilityBackslash(simplecpp::OutputList *outputList, const simplecpp::Location &location) +static void portabilityBackslash(simplecpp::OutputList * const outputList, const simplecpp::Location &location) { if (!outputList) return; @@ -999,7 +999,7 @@ void simplecpp::TokenList::constFold() } } -static bool isFloatSuffix(const simplecpp::Token *tok) +static bool isFloatSuffix(const simplecpp::Token * const tok) { if (!tok || tok->str().size() != 1U) return false; @@ -1010,7 +1010,7 @@ static bool isFloatSuffix(const simplecpp::Token *tok) static const std::string AND("and"); static const std::string BITAND("bitand"); static const std::string BITOR("bitor"); -static bool isAlternativeAndBitandBitor(const simplecpp::Token* tok) +static bool isAlternativeAndBitandBitor(const simplecpp::Token * const tok) { return isAlternativeBinaryOp(tok, AND) || isAlternativeBinaryOp(tok, BITAND) || isAlternativeBinaryOp(tok, BITOR); } @@ -2296,7 +2296,7 @@ namespace simplecpp { * @return token after B */ const Token *expandHashHash(TokenList &output, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set &expandedmacros, const std::vector ¶metertokens, bool expandResult=true) const { - Token *A = output.back(); + Token * const A = output.back(); if (!A) throw invalidHashHash(tok->location, name(), "Missing first argument"); if (!sameline(tok, tok->next) || !sameline(tok, tok->next->next)) @@ -3258,7 +3258,7 @@ static bool getFileId(const std::string &path, FileID &id) #endif } -simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList, FileDataCache cache) +simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector &filenames, const simplecpp::DUI &dui, simplecpp::OutputList * const outputList, FileDataCache cache) { #ifdef SIMPLECPP_WINDOWS if (dui.clearIncludeCache) @@ -3341,7 +3341,7 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, return cache; } -static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token *&tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList *outputList) +static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token *&tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList * const outputList) { const simplecpp::Token * const tok = tok1; const simplecpp::MacroMap::const_iterator it = tok->name ? macros.find(tok->str()) : macros.end(); @@ -3391,21 +3391,21 @@ static void getLocaltime(struct tm <ime) #endif } -static std::string getDateDefine(const struct tm *timep) +static std::string getDateDefine(const struct tm * const timep) { char buf[] = "??? ?? ????"; strftime(buf, sizeof(buf), "%b %d %Y", timep); return std::string("\"").append(buf).append("\""); } -static std::string getTimeDefine(const struct tm *timep) +static std::string getTimeDefine(const struct tm * const timep) { char buf[] = "??:??:??"; strftime(buf, sizeof(buf), "%H:%M:%S", timep); return std::string("\"").append(buf).append("\""); } -void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector &files, simplecpp::FileDataCache &cache, const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list *macroUsage, std::list *ifCond) +void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector &files, simplecpp::FileDataCache &cache, const simplecpp::DUI &dui, simplecpp::OutputList * const outputList, std::list * const macroUsage, std::list * const ifCond) { #ifdef SIMPLECPP_WINDOWS if (dui.clearIncludeCache) diff --git a/test.cpp b/test.cpp index 3a858929..952fe722 100644 --- a/test.cpp +++ b/test.cpp @@ -86,7 +86,7 @@ static void assertThrowFailed(int line) std::cerr << "exception not thrown" << std::endl; } -static void testcase(const std::string &name, void (*f)(), int argc, char * const *argv) +static void testcase(const std::string &name, void (*const f)(), int argc, char *argv[]) { if (argc == 1) { f(); @@ -101,7 +101,7 @@ static void testcase(const std::string &name, void (*f)(), int argc, char * cons #define TEST_CASE(F) (testcase(#F, F, argc, argv)) -static simplecpp::TokenList makeTokenList(const char code[], std::size_t size, std::vector &filenames, const std::string &filename=std::string(), simplecpp::OutputList *outputList=nullptr) +static simplecpp::TokenList makeTokenList(const char code[], std::size_t size, std::vector &filenames, const std::string &filename=std::string(), simplecpp::OutputList * const outputList=nullptr) { switch (USE_INPUT) { case Input::Stringstream: { @@ -115,24 +115,24 @@ static simplecpp::TokenList makeTokenList(const char code[], std::size_t size, s return simplecpp::TokenList{filenames}; // unreachable - needed for GCC and Visual Studio } -static simplecpp::TokenList makeTokenList(const char code[], std::vector &filenames, const std::string &filename=std::string(), simplecpp::OutputList *outputList=nullptr) +static simplecpp::TokenList makeTokenList(const char code[], std::vector &filenames, const std::string &filename=std::string(), simplecpp::OutputList * const outputList=nullptr) { return makeTokenList(code, strlen(code), filenames, filename, outputList); } -static std::string readfile(const char code[], simplecpp::OutputList *outputList=nullptr) +static std::string readfile(const char code[], simplecpp::OutputList * const outputList=nullptr) { std::vector files; return makeTokenList(code,files,std::string(),outputList).stringify(); } -static std::string readfile(const char code[], std::size_t size, simplecpp::OutputList *outputList=nullptr) +static std::string readfile(const char code[], std::size_t size, simplecpp::OutputList * const outputList=nullptr) { std::vector files; return makeTokenList(code,size,files,std::string(),outputList).stringify(); } -static std::string preprocess(const char code[], const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list *macroUsage = nullptr, std::list *ifCond = nullptr, const std::string &file = std::string()) +static std::string preprocess(const char code[], const simplecpp::DUI &dui, simplecpp::OutputList * const outputList, std::list * const macroUsage = nullptr, std::list * const ifCond = nullptr, const std::string &file = std::string()) { std::vector files; simplecpp::FileDataCache cache; @@ -160,17 +160,17 @@ static std::string preprocess(const char code[], const simplecpp::DUI &dui) return preprocess(code, dui, nullptr); } -static std::string preprocess(const char code[], simplecpp::OutputList *outputList) +static std::string preprocess(const char code[], simplecpp::OutputList * const outputList) { return preprocess(code, simplecpp::DUI(), outputList); } -static std::string preprocess(const char code[], std::list *ifCond) +static std::string preprocess(const char code[], std::list * const ifCond) { return preprocess(code, simplecpp::DUI(), nullptr, nullptr, ifCond); } -static std::string preprocess(const char code[], std::list *macroUsage) +static std::string preprocess(const char code[], std::list * const macroUsage) { return preprocess(code, simplecpp::DUI(), nullptr, macroUsage); } @@ -3960,7 +3960,7 @@ static void leak() } } -static void runTests(int argc, char **argv, Input input) +static void runTests(int argc, char *argv[], Input input) { USE_INPUT = input; @@ -4257,7 +4257,7 @@ static void runTests(int argc, char **argv, Input input) TEST_CASE(leak); } -int main(int argc, char **argv) +int main(int argc, char *argv[]) { runTests(argc, argv, Input::Stringstream); runTests(argc, argv, Input::CharBuffer); From 3672fd465d9afb23228eaa0659efcbfb382b2c8d Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 11 Jul 2026 10:43:43 +0200 Subject: [PATCH 08/11] disabled `-Wlifetime-safety-*` Clang warnings for now --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a90efae..837b07b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,11 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options_safe(-Wno-thread-safety-negative) add_compile_options_safe(-Wno-thread-safety-beta) + # TODO: enable + add_compile_options_safe(-Wno-lifetime-safety-intra-tu-suggestions) + add_compile_options_safe(-Wno-lifetime-safety-intra-tu-constructor-suggestions) + add_compile_options_safe(-Wno-lifetime-safety-cross-tu-constructor-suggestions) + # TODO: fix these? add_compile_options(-Wno-padded) add_compile_options(-Wno-sign-conversion) From c69e2f4daf49ce908ef8d263ef50c2ecaba03890 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 11 May 2026 15:28:11 +0200 Subject: [PATCH 09/11] mitigated `misc-explicit-constructor` clang-tidy warnings --- simplecpp.cpp | 2 +- simplecpp.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 2f6788d8..ec2604b3 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1699,7 +1699,7 @@ namespace simplecpp { }; struct invalidDirectiveAsMacroParameter : public Error { - invalidDirectiveAsMacroParameter(const Location &loc) + explicit invalidDirectiveAsMacroParameter(const Location &loc) : Error(loc, "it is invalid to use a preprocessor directive as macro parameter") {} }; diff --git a/simplecpp.h b/simplecpp.h index ee2eb100..d8fc12cd 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -75,6 +75,7 @@ namespace simplecpp { struct View { // cppcheck-suppress noExplicitConstructor + // NOLINTNEXTLINE(misc-explicit-constructor) View(const char* data) : mData(data) , mSize(strlen(data)) @@ -88,6 +89,7 @@ namespace simplecpp { {} // cppcheck-suppress noExplicitConstructor + // NOLINTNEXTLINE(misc-explicit-constructor) View(const std::string& str) : mData(str.data()) , mSize(str.size()) From b2a59ca728a13c9a9449f0cdd098654e91b36fa3 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 16 Apr 2026 13:58:49 +0200 Subject: [PATCH 10/11] fixed `readability-redundant-parentheses` clang-tidy warnings --- simplecpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index ec2604b3..0abd509c 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -799,7 +799,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, if (ch == '\\') { TokenString tmp; char tmp_ch = ch; - while ((stream.good()) && (tmp_ch == '\\' || tmp_ch == ' ' || tmp_ch == '\t')) { + while (stream.good() && (tmp_ch == '\\' || tmp_ch == ' ' || tmp_ch == '\t')) { tmp += tmp_ch; tmp_ch = stream.readChar(); } From 5378e953aeb3e071a975536ce84a0402742405eb Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 11 May 2026 15:29:18 +0200 Subject: [PATCH 11/11] mitigated `bugprone-assignment-in-selection-statement` clang-tidy warning --- simplecpp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/simplecpp.cpp b/simplecpp.cpp index 0abd509c..65e3535f 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3783,6 +3783,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL std::string header; if (systemheader) { + // NOLINTNEXTLINE(bugprone-assignment-in-selection-statement) while ((tok = tok->next) && tok->op != '>') header += tok->str(); if (tok && tok->op == '>')