diff --git a/.clang-tidy b/.clang-tidy index c03da523..806a8608 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -49,6 +49,7 @@ Checks: > -readability-magic-numbers, -readability-redundant-inline-specifier, -readability-simplify-boolean-expr, + -readability-use-concise-preprocessor-directives, -readability-uppercase-literal-suffix, -performance-avoid-endl, -performance-enum-size, diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 8bc15d1a..4b52d7bc 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 20 - sudo apt-get install clang-tidy-20 + sudo ./llvm.sh 21 + sudo apt-get install clang-tidy-21 - name: Verify clang-tidy configuration run: | - clang-tidy-20 --verify-config + clang-tidy-21 --verify-config - name: Prepare CMake run: | cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_EXPORT_COMPILE_COMMANDS=ON env: - CXX: clang-20 + CXX: clang-21 - name: Clang-Tidy run: | - run-clang-tidy-20 -q -j $(nproc) -p=cmake.output + run-clang-tidy-21 -q -j $(nproc) -p=cmake.output diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cc62e88..efdc0d96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,16 +49,25 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # no need for c++98 compatibility add_compile_options(-Wno-c++98-compat-pedantic) # these are not really fixable - add_compile_options(-Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables) + add_compile_options(-Wno-exit-time-destructors) + add_compile_options(-Wno-global-constructors) + add_compile_options(-Wno-weak-vtables) add_compile_options_safe(-Wno-unsafe-buffer-usage) + add_compile_options_safe(-Wno-nrvo) # we are not interested in these - add_compile_options(-Wno-multichar -Wno-four-char-constants) + add_compile_options(-Wno-multichar) + add_compile_options(-Wno-four-char-constants) # ignore C++11-specific warning - add_compile_options(-Wno-suggest-override -Wno-suggest-destructor-override) + add_compile_options(-Wno-suggest-override) + add_compile_options(-Wno-suggest-destructor-override) # contradicts -Wcovered-switch-default add_compile_options(-Wno-switch-default) # TODO: fix these? - add_compile_options(-Wno-padded -Wno-sign-conversion -Wno-implicit-int-conversion -Wno-shorten-64-to-32 -Wno-shadow-field-in-constructor) + add_compile_options(-Wno-padded) + add_compile_options(-Wno-sign-conversion) + add_compile_options(-Wno-implicit-int-conversion) + add_compile_options(-Wno-shorten-64-to-32) + add_compile_options(-Wno-shadow-field-in-constructor) if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 14 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) # TODO: verify this regression still exists in clang-15 diff --git a/simplecpp.cpp b/simplecpp.cpp index 799d6c9b..320836be 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -874,7 +874,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, back()->setstr(currentToken); location.adjust(currentToken); if (currentToken.find_first_of("\r\n") == std::string::npos) - location.col += 2 + 2 * delim.size(); + location.col += 2 + (2 * delim.size()); else location.col += 1 + delim.size(); @@ -1329,6 +1329,7 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok) void simplecpp::TokenList::constFoldQuestionOp(Token **tok1) { bool gotoTok1 = false; + // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data for (Token *tok = *tok1; tok && tok->op != ')'; tok = gotoTok1 ? *tok1 : tok->next) { gotoTok1 = false; if (tok->str() != "?") @@ -1508,7 +1509,12 @@ namespace simplecpp { } Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.files), valueDefinedInCode_(other.valueDefinedInCode_) { - *this = other; + // TODO: remove the try-catch - see #537 + // avoid bugprone-exception-escape clang-tidy warning + try { + *this = other; + } + catch (const Error&) {} // NOLINT(bugprone-empty-catch) } ~Macro() { @@ -1945,6 +1951,7 @@ namespace simplecpp { } } + // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data Token * const output_end_1 = output.back(); const Token *valueToken2; @@ -2250,7 +2257,7 @@ namespace simplecpp { const bool canBeConcatenatedStringOrChar = isStringLiteral_(A->str()) || isCharLiteral_(A->str()); const bool unexpectedA = (!A->name && !A->number && !A->str().empty() && !canBeConcatenatedWithEqual && !canBeConcatenatedStringOrChar); - Token * const B = tok->next->next; + const Token * const B = tok->next->next; if (!B->name && !B->number && B->op && !B->isOneOf("#=")) throw invalidHashHash::unexpectedToken(tok->location, name(), B); @@ -2528,11 +2535,11 @@ static void simplifySizeof(simplecpp::TokenList &expr, const std::mapnext) { if (tok->str() != "sizeof") continue; - simplecpp::Token *tok1 = tok->next; + const simplecpp::Token *tok1 = tok->next; if (!tok1) { throw std::runtime_error("missing sizeof argument"); } - simplecpp::Token *tok2 = tok1->next; + const simplecpp::Token *tok2 = tok1->next; if (!tok2) { throw std::runtime_error("missing sizeof argument"); } @@ -2547,7 +2554,7 @@ static void simplifySizeof(simplecpp::TokenList &expr, const std::mapnext) { + for (const simplecpp::Token *typeToken = tok1; typeToken != tok2; typeToken = typeToken->next) { if ((typeToken->str() == "unsigned" || typeToken->str() == "signed") && typeToken->next->name) continue; if (typeToken->str() == "*" && type.find('*') != std::string::npos) @@ -2598,11 +2605,11 @@ static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { if (tok->str() != HAS_INCLUDE) continue; - simplecpp::Token *tok1 = tok->next; + const simplecpp::Token *tok1 = tok->next; if (!tok1) { throw std::runtime_error("missing __has_include argument"); } - simplecpp::Token *tok2 = tok1->next; + const simplecpp::Token *tok2 = tok1->next; if (!tok2) { throw std::runtime_error("missing __has_include argument"); } @@ -2620,7 +2627,7 @@ static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI const bool systemheader = (tok1 && tok1->op == '<'); std::string header; if (systemheader) { - simplecpp::Token *tok3 = tok1->next; + const simplecpp::Token *tok3 = tok1->next; if (!tok3) { throw std::runtime_error("missing __has_include closing angular bracket"); } @@ -2631,7 +2638,7 @@ static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI } } - for (simplecpp::Token *headerToken = tok1->next; headerToken != tok3; headerToken = headerToken->next) + for (const simplecpp::Token *headerToken = tok1->next; headerToken != tok3; headerToken = headerToken->next) header += headerToken->str(); } else { header = tok1->str().substr(1U, tok1->str().size() - 2U); diff --git a/simplecpp.h b/simplecpp.h index 4675d1f3..c6c3b515 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -426,6 +426,7 @@ namespace simplecpp { std::pair get(const std::string &sourcefile, const std::string &header, const DUI &dui, bool systemheader, std::vector &filenames, OutputList *outputList); void insert(FileData data) { + // NOLINTNEXTLINE(misc-const-correctness) - FP FileData *const newdata = new FileData(std::move(data)); mData.emplace_back(newdata);