From 6e345f80ec834333dad466d576c6c00a92c51cb4 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Fri, 14 Nov 2025 21:57:17 +0100 Subject: [PATCH] Integrate (a nerfed version of) clang-tidy into CI. For now, it's integrated into core, main and scene only. Fix a few superficial clang-tidy failures. --- .clang-tidy | 15 ++--- .github/workflows/linux_builds.yml | 24 +++++++- .github/workflows/static_checks.yml | 1 + .pre-commit-config.yaml | 13 +++-- core/string/ucaps.h | 4 +- core/templates/iterable.h | 2 +- core/variant/method_ptrcall.h | 1 + scene/animation/easing_equations.h | 90 ++++++++++++++--------------- scene/main/scene_tree_fti_tests.h | 2 +- 9 files changed, 89 insertions(+), 63 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 05b2f61a7a..7e43549f9c 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,20 +1,17 @@ Checks: - -* - - cppcoreguidelines-pro-type-member-init - modernize-deprecated-headers - - modernize-redundant-void-arg - - modernize-use-bool-literals - - modernize-use-default-member-init - - modernize-use-nullptr - - readability-braces-around-statements - - readability-redundant-member-init +# - modernize-redundant-void-arg # TODO Re-activate +# - modernize-use-bool-literals # TODO Re-activate +# - modernize-use-default-member-init # TODO Re-activate +# - modernize-use-nullptr # TODO Re-activate +# - readability-braces-around-statements # TODO Re-activate +# - readability-redundant-member-init # TODO Re-activate HeaderFileExtensions: ["", h, hh, hpp, hxx, inc, glsl] ImplementationFileExtensions: [c, cc, cpp, cxx, m, mm, java] HeaderFilterRegex: (core|doc|drivers|editor|main|modules|platform|scene|servers|tests)/ FormatStyle: file CheckOptions: - cppcoreguidelines-pro-type-member-init.IgnoreArrays: true - cppcoreguidelines-pro-type-member-init.UseAssignment: true modernize-deprecated-headers.CheckHeaderFile: true modernize-use-bool-literals.IgnoreMacros: false modernize-use-default-member-init.IgnoreMacros: false diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index b722a07bc1..b25bb1a011 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -30,7 +30,7 @@ jobs: - name: Editor w/ Mono (target=editor) cache-name: linux-editor-mono target: editor - scons-flags: module_mono_enabled=yes + scons-flags: module_mono_enabled=yes compiledb=yes bin: ./bin/godot.linuxbsd.editor.x86_64.mono build-mono: true doc-test: true @@ -40,6 +40,7 @@ jobs: artifact: true # Validate godot-cpp compatibility on one arbitrary editor build. godot-cpp: true + clang-tidy: true - name: Editor with doubles and GCC sanitizers (target=editor, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=mold) cache-name: linux-editor-double-sanitizers @@ -114,6 +115,21 @@ jobs: uses: actions/checkout@v6 with: submodules: recursive + fetch-depth: 2 # 2 needed for Get changed files; no trivial way to conditionally use 1 + + # Keep in sync with static_checks.yml + - name: Get changed files + if: matrix.clang-tidy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + files=$(git diff-tree --no-commit-id --name-only -r HEAD^1..HEAD 2> /dev/null || true) + elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.forced }}" == "false" -a "${{ github.event.created }}" == "false" ]; then + files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true) + fi + files=$(echo "$files" | xargs -I {} sh -c 'echo "\"./{}\""' | tr '\n' ' ') + echo "CHANGED_FILES=$files" >> $GITHUB_ENV - name: Setup dependencies run: | @@ -181,6 +197,12 @@ jobs: platform: linuxbsd target: ${{ matrix.target }} + - name: Style checks via pre-commit + if: matrix.clang-tidy + uses: pre-commit/action@v3.0.1 + with: + extra_args: --files ${{ env.CHANGED_FILES }} --hook-stage manual clang-tidy + - name: Compilation (godot-cpp) uses: ./.github/actions/godot-cpp-build if: matrix.godot-cpp diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index 8d82975306..5ea2fb6620 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -19,6 +19,7 @@ jobs: run: | bash ./misc/scripts/gitignore_check.sh + # Keep in sync with linux_builds.yml - name: Get changed files env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 430329053f..0f18569de4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,16 +29,21 @@ repos: types_or: [text] args: [-style=file:misc/utility/clang_format_glsl.yml] + # Not automatically triggered (because it requires compile_commands.json to be up-to-date). + # Invoke it manually via `pre-commit run --hook-stage manual clang-tidy` - repo: https://github.com/pocc/pre-commit-hooks rev: v1.3.5 hooks: - id: clang-tidy - files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$ - args: [--fix, --quiet, --use-color] + # TODO .inc ignored for now because they don't include their parent header. + # TODO Platform-specific subfolders currently fail, we should try to include them + files: ^(core|main|scene)/.*\.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|java)$ + # No unknown warning suppression used for easier compatibility with gcc + args: [--fix, --quiet, --use-color, -p=compile_commands.json, -extra-arg=-Wno-unknown-warning-option] types_or: [text] additional_dependencies: [clang-tidy==21.1.6] - require_serial: true - stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy` + require_serial: false + stages: [manual] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.15.0 diff --git a/core/string/ucaps.h b/core/string/ucaps.h index ced2ccfbef..4344374763 100644 --- a/core/string/ucaps.h +++ b/core/string/ucaps.h @@ -3034,7 +3034,7 @@ static const int reverse_caps_table[UTL_LEN][2] = { { 0x1E921, 0x1E943 }, }; -static int _find_upper(int ch) { +inline int _find_upper(int ch) { int low = 0; int high = LTU_LEN - 1; int middle; @@ -3054,7 +3054,7 @@ static int _find_upper(int ch) { return ch; } -static int _find_lower(int ch) { +inline int _find_lower(int ch) { int low = 0; int high = UTL_LEN - 1; int middle; diff --git a/core/templates/iterable.h b/core/templates/iterable.h index 44c9b4d1f0..f531976aab 100644 --- a/core/templates/iterable.h +++ b/core/templates/iterable.h @@ -30,7 +30,7 @@ #pragma once -#include +#include template class Iterable { diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index c108e1a20f..ff2ae0cd94 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -30,6 +30,7 @@ #pragma once +#include "core/object/object.h" #include "core/object/object_id.h" #include "core/templates/simple_type.h" #include "core/typedefs.h" diff --git a/scene/animation/easing_equations.h b/scene/animation/easing_equations.h index a758910ab6..705ffdd5af 100644 --- a/scene/animation/easing_equations.h +++ b/scene/animation/easing_equations.h @@ -57,25 +57,25 @@ */ namespace Linear { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c * t / d + b; } }; // namespace Linear namespace Sine { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return -c * std::cos(t / d * (Math::PI / 2)) + c + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { return c * std::sin(t / d * (Math::PI / 2)) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { return -c / 2 * (std::cos(Math::PI * t / d) - 1) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -85,15 +85,15 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Sine namespace Quint { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c * std::pow(t / d, 5) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { return c * (std::pow(t / d - 1, 5) + 1) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { t = t / d * 2; if (t < 1) { @@ -102,7 +102,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return c / 2 * (std::pow(t - 2, 5) + 2) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -112,15 +112,15 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Quint namespace Quart { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c * std::pow(t / d, 4) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { return -c * (std::pow(t / d - 1, 4) - 1) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { t = t / d * 2; if (t < 1) { @@ -129,7 +129,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return -c / 2 * (std::pow(t - 2, 4) - 2) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -139,16 +139,16 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Quart namespace Quad { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c * std::pow(t / d, 2) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { t /= d; return -c * t * (t - 2) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { t = t / d * 2; if (t < 1) { @@ -157,7 +157,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return -c / 2 * ((t - 1) * (t - 3) - 1) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -167,21 +167,21 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Quad namespace Expo { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { if (t == 0) { return b; } return c * std::pow(2, 10 * (t / d - 1)) + b - c * 0.001; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { if (t == d) { return b + c; } return c * 1.001 * (-std::pow(2, -10 * t / d) + 1) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { if (t == 0) { return b; } @@ -198,7 +198,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return c / 2 * 1.0005 * (-std::pow(2, -10 * (t - 1)) + 2) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -208,7 +208,7 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Expo namespace Elastic { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { if (t == 0) { return b; } @@ -226,7 +226,7 @@ static real_t in(real_t t, real_t b, real_t c, real_t d) { return -(a * std::sin((t * d - s) * (2 * Math::PI) / p)) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { if (t == 0) { return b; } @@ -242,7 +242,7 @@ static real_t out(real_t t, real_t b, real_t c, real_t d) { return (c * std::pow(2, -10 * t) * std::sin((t * d - s) * (2 * Math::PI) / p) + c + b); } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { if (t == 0) { return b; } @@ -266,7 +266,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return a * std::sin((t * d - s) * (2 * Math::PI) / p) * 0.5f + c + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -276,17 +276,17 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Elastic namespace Cubic { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { t /= d; return c * t * t * t + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { t = t / d - 1; return c * (t * t * t + 1) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { t /= d / 2; if (t < 1) { return c / 2 * t * t * t + b; @@ -296,7 +296,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return c / 2 * (t * t * t + 2) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -306,17 +306,17 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Cubic namespace Circ { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { t /= d; return -c * (std::sqrt(1 - t * t) - 1) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { t = t / d - 1; return c * std::sqrt(1 - t * t) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { t /= d / 2; if (t < 1) { return -c / 2 * (std::sqrt(1 - t * t) - 1) + b; @@ -326,7 +326,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return c / 2 * (std::sqrt(1 - t * t) + 1) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -336,7 +336,7 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Circ namespace Bounce { -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { t /= d; if (t < (1 / 2.75f)) { @@ -357,11 +357,11 @@ static real_t out(real_t t, real_t b, real_t c, real_t d) { return c * (7.5625f * t * t + 0.984375f) + b; } -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c - out(d - t, 0, c, d) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return in(t * 2, b, c / 2, d); } @@ -369,7 +369,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return out(t * 2 - d, b + h, h, d); } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -379,21 +379,21 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Bounce namespace Back { -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { float s = 1.70158f; t /= d; return c * t * t * ((s + 1) * t - s) + b; } -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { float s = 1.70158f; t = t / d - 1; return c * (t * t * ((s + 1) * t + s) + 1) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { float s = 1.70158f * 1.525f; t /= d / 2; @@ -405,7 +405,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b; } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } @@ -415,18 +415,18 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { }; // namespace Back namespace Spring { -static real_t out(real_t t, real_t b, real_t c, real_t d) { +inline real_t out(real_t t, real_t b, real_t c, real_t d) { t /= d; real_t s = 1.0 - t; t = (std::sin(t * Math::PI * (0.2 + 2.5 * t * t * t)) * std::pow(s, 2.2) + t) * (1.0 + (1.2 * s)); return c * t + b; } -static real_t in(real_t t, real_t b, real_t c, real_t d) { +inline real_t in(real_t t, real_t b, real_t c, real_t d) { return c - out(d - t, 0, c, d) + b; } -static real_t in_out(real_t t, real_t b, real_t c, real_t d) { +inline real_t in_out(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return in(t * 2, b, c / 2, d); } @@ -434,7 +434,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) { return out(t * 2 - d, b + h, h, d); } -static real_t out_in(real_t t, real_t b, real_t c, real_t d) { +inline real_t out_in(real_t t, real_t b, real_t c, real_t d) { if (t < d / 2) { return out(t * 2, b, c / 2, d); } diff --git a/scene/main/scene_tree_fti_tests.h b/scene/main/scene_tree_fti_tests.h index 38e80b0ed2..b3171bf6b0 100644 --- a/scene/main/scene_tree_fti_tests.h +++ b/scene/main/scene_tree_fti_tests.h @@ -30,7 +30,7 @@ #pragma once -#include +#include class Node3D; class Node;