Skip to content

Add CMake clang-tidy integration, enable in CI, and fix all clang-tidy errors#30

Merged
achamayou merged 31 commits into
mainfrom
copilot/add-cmake-flag-clang-tidy
May 12, 2026
Merged

Add CMake clang-tidy integration, enable in CI, and fix all clang-tidy errors#30
achamayou merged 31 commits into
mainfrom
copilot/add-cmake-flag-clang-tidy

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 23, 2026

Adds idiomatic CMake support for running clang-tidy during builds via per-target CXX_CLANG_TIDY properties, activates it in CI, and fixes all resulting clang-tidy errors across the codebase.

  • CMakeLists.txt: New CLANG_TIDY option (default OFF). When enabled, uses find_program to locate clang-tidy and sets the CXX_CLANG_TIDY property per-target via add_unit_test(), avoiding running clang-tidy on third-party sources (e.g., EverCrypt).
  • .github/workflows/ci.yml: Install clang-tidy on Ubuntu runners; pass -DCLANG_TIDY=ON and -DCMAKE_EXPORT_COMPILE_COMMANDS=ON for all Linux builds. Added a dedicated "Clang-Tidy Header" CI step that runs clang-tidy directly on merklecpp.h using the compile database, since the header-only library is not compiled as a translation unit.
  • .clang-tidy: New configuration file with curated check categories, treating all warnings as errors (WarningsAsErrors: '*'), and using the existing .clang-format for formatting (FormatStyle: file). Enables broadly applicable categories (bugprone-*, cert-*, clang-analyzer-*, concurrency-*, cppcoreguidelines-*, hicpp-*, misc-*, modernize-*, performance-*, portability-*, readability-*) while excluding project/company/platform-specific and overly opinionated checks.
  • merklecpp.h: Fixed all clang-tidy findings including braces, const-correctness, using instead of typedef, [[nodiscard]], noexcept on move constructors, std::move for rvalue ref params, null-pointer guard, and more.
  • Test files: Fixed all clang-tidy errors across all test files (#defineconstexpr, std::endl'\n', braces, const, static_cast, split declarations, nullptr, narrowing/widening conversions, etc.). Fixed a real bug in retract.cpp: a std::runtime_error was constructed but never thrown.
  • past_root() verification: Investigated a reviewer concern about past_root() only handling PATH_LEFT direction elements. Confirmed this is intentionally correct: PATH_LEFT elements represent sibling subtrees from the past state, while PATH_RIGHT elements represent future state and must be skipped. Added a deterministic test verifying past_root() at every leaf index for trees of size 2–64.
cmake -DTESTS=ON -DCLANG_TIDY=ON ..

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 23, 2026 10:31
- Add CLANG_TIDY option to CMakeLists.txt that sets CMAKE_CXX_CLANG_TIDY
  using find_program to locate clang-tidy
- Install clang-tidy in CI workflow
- Pass -DCLANG_TIDY=ON for Linux CI builds

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copilot AI changed the title [WIP] Add CMake flag to enable clang-tidy during build Add CMake clang-tidy integration and enable in CI Feb 23, 2026
Copilot AI requested a review from achamayou February 23, 2026 10:32
Comment thread CMakeLists.txt Outdated
@achamayou
Copy link
Copy Markdown
Member

@copilot add a .clang-tidy configuration that enables warnings as errors, uses FormatStyle "file", and enables all categories of errors.

…tStyle file

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot add a .clang-tidy configuration that enables warnings as errors, uses FormatStyle "file", and enables all categories of errors.

Added .clang-tidy in 129d9b4 with Checks: '*', WarningsAsErrors: '*', and FormatStyle: file. Note that enabling all checks will cause build failures on the existing codebase (e.g., llvmlibc-*, fuchsia-*, altera-* checks). You may want to selectively disable non-applicable checks with -checkname entries.

@achamayou
Copy link
Copy Markdown
Member

@copilot you make a good point, can you enable all the sensible checks you can think of then, and not the ones that are project or company dependent?

Note that enabling all checks will cause build failures on the existing codebase (e.g., llvmlibc-, fuchsia-, altera-* checks). You may want to selectively disable non-applicable checks with -checkname entries.

…t/company-specific ones

Enable: bugprone, cert, clang-analyzer, concurrency, cppcoreguidelines,
hicpp, misc, modernize, performance, portability, readability.

Exclude: abseil, altera, android, boost, darwin, fuchsia, google,
linuxkernel, llvm, llvmlibc, mpi, objc, openmp, zircon.

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot you make a good point, can you enable all the sensible checks you can think of then, and not the ones that are project or company dependent?

Note that enabling all checks will cause buil...

Updated in 02e2456. The .clang-tidy now enables only broadly applicable categories: bugprone-*, cert-*, clang-analyzer-*, concurrency-*, cppcoreguidelines-*, hicpp-*, misc-*, modernize-*, performance-*, portability-*, readability-*.

Excluded project/company/platform-specific categories: abseil-*, altera-*, android-*, boost-*, darwin-*, fuchsia-*, google-*, linuxkernel-*, llvm-*, llvmlibc-*, mpi-*, objc-*, openmp-*, zircon-*.

@achamayou
Copy link
Copy Markdown
Member

@copilot great, now run the build step you have modified to add clang tidy, look a errors it produces, and makes the necessary changes to the code to fix them.

Copilot AI and others added 4 commits February 23, 2026 11:44
- Replace #define with constexpr for PRINT_HASH_SIZE
- Add braces to single-statement for loops and if blocks
- Add const to variables that are not modified
- Replace std::endl with '\n'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace #define HSZ with constexpr size_t
- Fix implicit widening of multiplication with static_cast
- Add braces around single-line if body
- Add const to seconds variable
- Fix narrowing conversion with static_cast<double>
- Replace std::endl with '\n'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace macro with constexpr variable
- Add const qualifiers where appropriate
- Use nullptr instead of 0 for std::time
- Replace std::endl with newline character
- Use static_cast instead of C-style casts
- Split multi-variable declaration
- Use range-based for loop
- Add braces around single-line if body
- Fix implicit bool conversion

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace macro with constexpr
- Add const qualifiers where appropriate
- Use nullptr instead of 0 for std::time
- Replace std::endl with '\n'
- Fix implicit widening with static_cast
- Split multiple variable declarations
- Use auto with static_cast instead of C-style casts
- Add braces around single-statement blocks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@achamayou achamayou marked this pull request as ready for review April 21, 2026 13:57
Copilot AI review requested due to automatic review settings April 21, 2026 13:57
Comment thread test/retract.cpp
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds first-class clang-tidy support to the CMake build and CI pipeline, introduces a repository .clang-tidy configuration, and updates the library header and multiple test programs to satisfy clang-tidy checks.

Changes:

  • Add a CLANG_TIDY CMake option and enable clang-tidy in Ubuntu CI builds.
  • Add a curated .clang-tidy config and a CI step to run clang-tidy on merklecpp.h.
  • Refactor/fix various test and header code patterns to address clang-tidy findings (casts, const-correctness, braces, iostream usage, etc.).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
CMakeLists.txt Adds CLANG_TIDY option and wires clang-tidy into CMake builds.
.github/workflows/ci.yml Installs clang-tidy on Ubuntu and runs it in CI (including a header check).
.clang-tidy Adds project-wide clang-tidy ruleset with warnings-as-errors.
merklecpp.h Multiple clang-tidy-driven refactors and safety checks in core types/algorithms.
test/time_large_trees.cpp Modernizes constants/printing/casts and timing calculations.
test/serialise_to_file.cpp Updates constants/loops and file I/O style.
test/serialisation.cpp Refactors constants/casts/printing; minor structural changes.
test/retract.cpp Refactors constants/casts/printing; adjusts a retract invariant check.
test/paths.cpp Refactors constants/casts/printing and adds explicit error branches.
test/past_root.cpp Refactors constants/casts/printing and adds braces.
test/past_paths.cpp Refactors constants/casts/printing; removes unused main args; adds braces.
test/partial_serialisation.cpp Refactors constants/casts/printing; adds braces.
test/flush.cpp Refactors constants/casts/printing; updates insertion loop.
test/demo_tree.cpp Refactors constants/printing and adds braces for single-line conditionals.
test/compare_hash_functions.cpp Refactors constants/printing/typedefs and improves const-correctness.
Comments suppressed due to low confidence (1)

test/serialise_to_file.cpp:63

  • The file read loop uses while (!f.eof()) and unconditionally push_back(t) after read(). This commonly appends an extra byte (the last value of t) when the final read() fails. Prefer a loop that only pushes when the read succeeds (e.g., while (f.read(&t, 1))).
        while (!f.eof())
        {
          f.read(&t, 1);
          bytes.push_back(t);
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread merklecpp.h Outdated
Comment thread merklecpp.h
Comment thread test/serialisation.cpp Outdated
Comment thread test/partial_serialisation.cpp Outdated
Comment thread CMakeLists.txt Outdated
Comment thread test/time_large_trees.cpp
Comment thread merklecpp.h Outdated
Comment thread merklecpp.h Outdated
achamayou and others added 4 commits May 12, 2026 17:28
Co-authored-by: cjen1-msft <chrisjensen@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
achamayou and others added 3 commits May 12, 2026 17:36
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Move clang-tidy from global CMAKE_CXX_CLANG_TIDY to per-target
CXX_CLANG_TIDY property set in add_unit_test(). This avoids running
clang-tidy on third-party sources (e.g., EverCrypt) which would fail
with warnings-as-errors. Also fix const on seconds variable in
time_large_trees.cpp by introducing ec_seconds for the EVERCRYPT block.

Agent-Logs-Url: https://github.com/microsoft/merklecpp/sessions/6de1fbaf-7309-4ea8-a9fa-40d9a24c65bc

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copilot AI requested a review from achamayou May 12, 2026 16:43
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 12, 2026

@achamayou Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 1c09f2e7-c3ef-4d80-8f68-1dad7d7f7e58

Sorry for the inconvenience!

@achamayou
Copy link
Copy Markdown
Member

@copilot try again

Copilot AI and others added 2 commits May 12, 2026 17:06
…rect

The copilot-pull-request-reviewer flagged past_root() for only handling
PATH_LEFT direction elements. Investigation shows this is intentionally
correct: in a Merkle tree path, PATH_LEFT elements represent sibling
subtrees added *before* the target index (part of the past state), while
PATH_RIGHT elements represent subtrees added *after* (future state).
Skipping PATH_RIGHT is the correct algorithm for computing past roots.

Added a deterministic test that verifies past_root at every leaf index
for trees of size 2-64, ensuring both PATH_LEFT and PATH_RIGHT path
elements are exercised. Also changed the loop variable from copy (auto)
to const reference (const auto&) for efficiency.

Agent-Logs-Url: https://github.com/microsoft/merklecpp/sessions/0475cd6b-501c-4961-ac1a-e2cfe1c0f89d

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 12, 2026

@copilot try again

Ran the full build with clang-tidy in both Debug and Release modes (-DTESTS=ON -DOPENSSL=ON -DCLANG_TIDY=ON), plus the header scan. Zero clang-tidy errors across all configurations and all 11 tests pass. The codebase is clean as of 0957e5e.

@achamayou achamayou merged commit 3f799bc into main May 12, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants