diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..993242e --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,55 @@ +Checks: > + readability-identifier-naming, + readability-implicit-bool-conversion, + misc-const-correctness, + -clang-diagnostic-error + +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: lower_case + - key: readability-identifier-naming.StructCase + value: lower_case + + - key: readability-identifier-naming.FunctionCase + value: lower_case + - key: readability-identifier-naming.MethodCase + value: lower_case + - key: readability-identifier-naming.MethodIgnoredRegexp + value: '^[A-Z][A-Z0-9_]*$' + + - key: readability-identifier-naming.VariableCase + value: lower_case + - key: readability-identifier-naming.VariableIgnoredRegexp + value: '^[A-Z][A-Z0-9_]*$' + - key: readability-identifier-naming.LocalVariableCase + value: lower_case + - key: readability-identifier-naming.ParameterCase + value: lower_case + + - key: readability-identifier-naming.MemberCase + value: lower_case + - key: readability-identifier-naming.MemberIgnoredRegexp + value: '^([A-Z][A-Z0-9_]*|[a-z][a-z0-9_]*_)$' + - key: readability-identifier-naming.PrivateMemberSuffix + value: '_' + - key: readability-identifier-naming.ProtectedMemberSuffix + value: '_' + - key: readability-identifier-naming.ConstantMemberIgnoredRegexp + value: '^[A-Z][A-Z0-9_]*$' + + - key: readability-identifier-naming.EnumConstantCase + value: UPPER_CASE + + - key: readability-identifier-naming.EnumCase + value: lower_case + + - key: readability-identifier-naming.TemplateParameterCase + value: CamelCase + + - key: readability-identifier-naming.NamespaceCase + value: lower_case + + - key: readability-identifier-naming.TypeAliasCase + value: lower_case + - key: readability-identifier-naming.TypeAliasIgnoredRegexp + value: '^[A-Z]$' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96b8fb5..8f93def 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,10 +118,27 @@ jobs: find include tests -name "*.h" -o -name "*.cpp" | \ xargs clang-format --dry-run --Werror + clang-tidy: + name: Clang Tidy + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + - name: Install clang-tidy-19 + run: | + wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc + echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee /etc/apt/sources.list.d/llvm.list + sudo apt-get update + sudo apt-get install -y clang-tidy-19 + - name: Check formatting + run: | + find include -name "*.h" -o -name "*.cpp" | \ + xargs -I{} clang-tidy-19 {} -- -x c++ -std=c++20 -I include -include cstdint -include cstddef + all-checks: name: All Checks runs-on: ubuntu-latest if: github.event_name == 'pull_request' - needs: [unittests, clang-format] + needs: [unittests, clang-format, clang-tidy] steps: - run: echo "All checks passed" diff --git a/include/pvm/engine/architecture.h b/include/pvm/engine/architecture.h index c966a7b..1bc041d 100644 --- a/include/pvm/engine/architecture.h +++ b/include/pvm/engine/architecture.h @@ -39,8 +39,8 @@ namespace ngu::pvm { std::uint64_t rng_state{entropy}; for (std::size_t i{count - 1}; i > 0; i--) { rng_state = lcg_next(rng_state); - std::size_t j{rng_state % (i + 1)}; - std::uint8_t tmp{arr[i]}; + std::size_t const j{rng_state % (i + 1)}; + std::uint8_t const tmp{arr[i]}; arr[i] = arr[j]; arr[j] = tmp; } diff --git a/include/pvm/engine/instructions.h b/include/pvm/engine/instructions.h index c55da7e..ab7ce7d 100644 --- a/include/pvm/engine/instructions.h +++ b/include/pvm/engine/instructions.h @@ -108,7 +108,7 @@ namespace ngu::pvm { auto const val = ctx->get_reg(insn.destination()); auto shift = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); shift &= 63; - ctx->set_reg(insn.destination(), (val << shift) | (val >> (64 - shift))); + ctx->set_reg(insn.destination(), shift != 0 ? (val << shift) | (val >> (64 - shift)) : val); } }; @@ -117,7 +117,7 @@ namespace ngu::pvm { auto const val = ctx->get_reg(insn.destination()); auto shift = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); shift &= 63; - ctx->set_reg(insn.destination(), (val >> shift) | (val << (64 - shift))); + ctx->set_reg(insn.destination(), shift != 0 ? (val >> shift) | (val << (64 - shift)) : val); } }; @@ -166,7 +166,7 @@ namespace ngu::pvm { struct jne_base { PVM_FORCEINLINE static void impl(context* ctx, const insn_view& insn) { - if (!(ctx->get_flags() & 1)) { + if ((ctx->get_flags() & 1) == 0u) { auto const offset = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); ctx->jump(ctx->get_pc() + insn.size() + offset); } @@ -175,7 +175,7 @@ namespace ngu::pvm { struct je_base { PVM_FORCEINLINE static void impl(context* ctx, const insn_view& insn) { - if (ctx->get_flags() & 1) { + if ((ctx->get_flags() & 1) != 0u) { auto const offset = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); ctx->jump(ctx->get_pc() + insn.size() + offset); } @@ -184,7 +184,7 @@ namespace ngu::pvm { struct jnei_base { PVM_FORCEINLINE static void impl(context* ctx, const insn_view& insn, const insn_stream_rt& insn_entries) { - if (!(ctx->get_flags() & 1)) { + if ((ctx->get_flags() & 1) == 0u) { auto const pos = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); if (pos >= insn_entries.size()) { @@ -198,7 +198,7 @@ namespace ngu::pvm { struct jei_base { PVM_FORCEINLINE static void impl(context* ctx, const insn_view& insn, const insn_stream_rt& insn_entries) { - if (ctx->get_flags() & 1) { + if ((ctx->get_flags() & 1) != 0u) { auto const pos = insn.has_immediate() ? insn.immediate() : ctx->get_reg(insn.source()); if (pos >= insn_entries.size()) {