Skip to content

ci: check headers with include-what-you-use - #77

Open
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1785319396-iwyu-ci
Open

ci: check headers with include-what-you-use#77
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1785319396-iwyu-ci

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an iwyu CI job that runs include-what-you-use (Ubuntu 26.04's iwyu package, clang 19-based) over every src/ library header, and fixes all its findings so the check starts green.

The job mirrors the coverage-stub approach: one stub TU per header (#include "x.hpp" // IWYU pragma: keep) compiled with -std=c++23 -I src, checked with -Xiwyu --check_also=src/x.hpp -Xiwyu --error=1, fanned out with xargs -P. Suggestions surface as ::error file=src/x.hpp annotations plus the full iwyu report.

.iwyu.imp maps away libstdc++ false positives so only real issues fail:

  • symbol pins preferring the <c*> spellings (assert<cassert>, size_t<cstddef>, intN_t<cstdint>, ...);
  • symbol pins for std::vector/std::pair/std::swap/std::size, which libstdc++ 15 re-exports from unrelated headers (iwyu otherwise suggests <format> // for vector);
  • <exception> treated as provided by <utility> (libstdc++'s std::swap(exception_ptr&, ...) overload otherwise makes iwyu demand <exception> for any std::swap call).

Header fixes (mostly fix_include-applied, then hand-tidied):

  • bm.hpp, geometry/point3d.hpp, hash_map.hpp, mcmf.hpp: replace <bits/stdc++.h> with the specific standard headers.
  • fft/all.hpp: wrapped in IWYU pragma: begin_exports/end_exports and switched to "fft/..." include paths like the other fft headers.
  • Everywhere else: add missing direct includes (e.g. <utility> for std::swap, <functional> for std::less defaults, "fft/common.hpp"/"fft/engine.hpp" where used directly), drop a few unused ones (<cassert> in manacher.hpp, "fft/common.hpp" in fft/engine.hpp, a redundant fwd-decl in dirichlet_series.hpp), and sort include lists.

Verified locally in an ubuntu:26.04 container (iwyu clean on all 50 headers), plus cmake --build && ctest (102/102 pass), scripts/bundle.py --all --check, and -fsyntax-only compiles of all verify/ solutions with g++-15.

Link to Devin session: https://app.devin.ai/sessions/fe0dc8e65b874385b5ad5387cec1e595
Requested by: @ecnerwala


Open in Devin Review (Beta)

Co-Authored-By: Andrew He <he.andrew.mail@gmail.com>
@ecnerwala ecnerwala self-assigned this Jul 29, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@beta-devin-ai-integration beta-devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 1 additional finding in Devin Review.

Open in Devin Review (Beta)

#include <utility>
#include <array>
#include <tuple>
#include <cstdlib>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Two library headers still fail to compile on their own because a needed standard header is missing

The include list is rewritten and sorted (#include <cstdlib> at src/quaternion_hurwitz.hpp:4) without adding the standard header that supplies assert, so anyone including this header on its own gets a compile failure the moment the checking code runs.
Impact: Users who include these headers first (without a catch-all include) hit build errors instead of a working library.

Why the new include audit misses the missing

src/quaternion_hurwitz.hpp:18 uses assert(...) inside a constructor template, and src/tensor.hpp:30 and src/tensor.hpp:57 use assert(...) inside member templates, but neither header includes <cassert> (see the rewritten include blocks at src/quaternion_hurwitz.hpp:3-7 and src/tensor.hpp:3-6).

The new iwyu job compiles a stub that only includes the header, so these templates are never instantiated and the undeclared assert is never diagnosed; the check therefore passes while the headers remain non-self-contained. Both files are touched by this PR's include cleanup, so <cassert> should be added.

Suggested change
#include <cstdlib>
#include <cassert>
#include <cstdlib>
Open in Devin Review (Beta)

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/seg_tree.hpp
@@ -1,6 +1,7 @@
#include <cassert>
#include <array>
#include <cassert>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 One library header has no protection against being included twice

The header's top-of-file include list is rewritten (#include <cassert> at src/seg_tree.hpp:2) while the file still starts without the one-time-inclusion marker every other header has, so including it twice in one program breaks the build with duplicate definitions.
Impact: Any program that pulls this header in through two different paths fails to compile.

Missing #pragma once

Every other library header begins with #pragma once (e.g. src/bit.hpp:1, src/tensor.hpp:1), but src/seg_tree.hpp starts directly with its includes, so a second inclusion re-defines seg_tree::floor_log_2, seg_tree::point, seg_tree::range, etc.

This is pre-existing, but the PR edits exactly these first lines as part of the header-hygiene pass, and the new iwyu stub (one include per TU) cannot detect it.

Prompt for agents
src/seg_tree.hpp lacks the `#pragma once` include guard that all other headers in src/ start with, so including it twice in a translation unit produces redefinition errors for everything in namespace seg_tree. Add `#pragma once` followed by a blank line before the include block, matching the convention in the rest of src/.
Open in Devin Review (Beta)

Was this helpful? React with 👍 or 👎 to provide feedback.

@github-actions

Copy link
Copy Markdown

GCC Code Coverage Report

📂 Overall coverage

Metric Coverage
Lines 🟡 7567/9302 (81.3%)
Functions 🟢 1003/1107 (90.6%)
Branches 🟡 6031/7712 (78.2%)

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.

1 participant