Skip to content

Add [\!shouldfail] reproducer for transitive implicit-dep tracking bug#50

Merged
typeless merged 1 commit into
mainfrom
reproducer/transitive-implicit-dep
May 15, 2026
Merged

Add [\!shouldfail] reproducer for transitive implicit-dep tracking bug#50
typeless merged 1 commit into
mainfrom
reproducer/transitive-implicit-dep

Conversation

@typeless

Copy link
Copy Markdown
Owner

Replaces #48 (closed when its base branch feature/show-index was deleted on merge of #49--delete-branch killed the dependent PR rather than retargeting it).

Summary

Adds a minimal failing reproducer for a real bug in pup's implicit-dep recording, tagged [\!shouldfail] so CI stays green while the bug is on file. Uses pup show index (just landed via #49) for forensic diagnostic output.

The bug

When an already-tracked header is edited to #include a new header, the source's recompile produces a .d file listing the new header, but pup's index does not extend the source's implicit-dep set to include it. Subsequent edits to the newly-introduced header are then invisible to change detection — pup reports Nothing to do (up to date). while the .o is stale.

This is distinct from the scope-filter bug fixed in 315b2a2. That one was an existing recorded header being filtered out during change detection. This is a header never recorded in the first place. It fires unscoped.

Reproducer (see test/e2e/fixtures/header_dep_transitive/test.sh)

  1. main.c includes only old.h. Initial build records old.h as implicit dep. .o contains 0x1 (ANSWER=1). ✓
  2. Edit old.h to #include "newhdr.h" and use EXTRA. Rebuild. .o contains 0x64 (EXTRA=100). ✓ (compile happened, .d listed newhdr.h)
  3. Edit newhdr.h (EXTRA 100 → 7777). Rebuild expected. Observed: Nothing to do. .o stays at 0x64. ✗

Between steps 2 and 3, test.sh runs pup show index PATTERN and reports whether newhdr.h appears in main.c's implicit-dep set. Live result on this branch:

implicit: src/main.c
implicit: /usr/include/stdc-predef.h
implicit: include/old.h          ← recorded ✓
                                 ← newhdr.h missing ✗
sticky:   src/Tupfile

This isolates the root cause precisely: pup's post-execution .d-file processing does not extend the implicit-dep set with newly-discovered transitive headers. The bug is in the dep-recording path (around discovered_deps / process_implicit_deps in cmd_build.cpp), not in change detection.

Why [\!shouldfail]

Catch2's [\!shouldfail] marks the test as an expected-failure: it runs, output is captured, exit status reports 1 failed as expected. Default CI stays green. Once the dep-recording bug is fixed and the test passes, removing the tag converts it into a regression guard.

Test plan

  • Reproducer runs standalone: bash test/e2e/fixtures/header_dep_transitive/test.sh exits 1 with diagnostic output showing stale .o AND the forensic from pup show index pinpointing the missing edge
  • Catch2 SCENARIO via ./build/test/unit/putup_test "[\!shouldfail]" reports 1 failed as expected
  • Full test suite is green (the SCENARIO does not break CI)
  • make format clean

Refs pup-header-detection-bug.md (working notes).

🤖 Generated with Claude Code

Minimal fixture demonstrating that pup fails to record a newly-transitive header when an existing tracked header is edited to include it. After the edit, the source's recompile produces a .d file listing the new header, but pup's implicit-dep set is not extended — so subsequent edits to the new header are invisible to change detection and pup reports "Nothing to do" while the .o is stale.

Reproducer (test.sh):
  1. source.c includes only old.h. Build, record old.h as implicit dep.
  2. Edit old.h to also #include newhdr.h. Rebuild. .o picks up new value via newhdr.h.
  3. Edit newhdr.h. Rebuild expected; pup reports "Nothing to do". .o stale.

Tagged [\!shouldfail] so default CI stays green while the bug is on file. Once the underlying dep-recording bug is fixed, removing the tag converts this into a regression guard.

The bug reproduces unscoped (no scope filter) and is distinct from the change-detection scope-filter bug fixed in 315b2a2 — that one was about an existing recorded header being filtered out; this is about a header never being recorded in the first place.

Refs pup-header-detection-bug.md (working notes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@typeless typeless merged commit d71e75b into main May 15, 2026
9 checks passed
@typeless typeless deleted the reproducer/transitive-implicit-dep branch May 15, 2026 06:41
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