Skip to content

win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c - #96

Merged
medvednikov merged 4 commits into
vlang:thirdparty-windows-amd64from
quaesitor-scientiam:fix-windows-intrin-dbghelp-headers
Sep 30, 2026
Merged

medvednikov merged 4 commits into
vlang:thirdparty-windows-amd64from
quaesitor-scientiam:fix-windows-intrin-dbghelp-headers

Conversation

@quaesitor-scientiam

@quaesitor-scientiam quaesitor-scientiam commented Sep 27, 2026 •

Copy link
Copy Markdown

Summary

vlang/v's vc/v_win.c bootstrap snapshot is always generated with
-cc msvc (see vlang/v's .github/workflows/gen_vc_ci.yml), which
makes its cgen emit unconditional #include <intrin.h> and
#include <dbghelp.h> under #ifdef _WIN32 (see vlang/v's
vlib/v/gen/c/cleanc.v, the g.ccompiler == 'msvc' branch). This
toolchain ships neither header, so ./makev.bat's default TCC-first
bootstrap path fails immediately on a fresh Windows clone of vlang/v,
before reaching any real code:

./vc/v_win.c:1168: error: include file 'intrin.h' not found

This PR adds both headers:

  • include/intrin.h — an empty compatibility stub (see the file's own
    comment for why: an earlier revision of this PR ported the real
    mingw-w64 header, but include/_mingw.h unconditionally
    #define __INTRIN_H_ — that header's own guard — so with
    <windows.h> included first (the real vc/v_win.c order), its body
    was silently skipped entirely, and used standalone it failed outright
    on missing crtdefs.h/psdk_inc/intrin-impl.h, neither shipped in
    this bundle; caught by @medvednikov's review, reverted in 2a102c9).
    None of the MSVC intrinsics vlang's cgen can emit (_umul128,
    _udiv128, _addcarry_u64, _BitScanForward, _BitScanForward64)
    are ever actually called when tcc compiles vc/v_win.c — every call
    site is wrapped in #if defined(_MSC_VER) at the C level — and
    _BitScanForward/_BitScanForward64/__faststorefence are already
    implemented for tcc in include/winapi/winnt.h via
    vlang-header-compat.patch. So the stub costs nothing.
  • include/dbghelp.h — the real mingw-w64 header (public domain, no
    copyright assigned — same provenance as the include/winapi/*.h
    files already vendored in this bundle), plus its small dependency
    chain: include/psdk_inc/_dbg_LOAD_IMAGE.h,
    include/psdk_inc/_dbg_common.h, and the pack-pragma helpers
    include/pshpack4.h / include/poppack.h. Unlike intrin.h, this
    one is NOT include-order-independent — its own top comment (added in
    da89255) documents that it requires <windows.h> first, which
    matches vc/v_win.c's actual order and is not a problem for this
    bundle's only consumer.

This change is additive: it lets the #include lines resolve, with no
risk of redefinition (verified) or behavior change to existing code.

Test plan

  • Fresh vlang/v checkout (commit c4998cf, later 73956465)
    with this bundle's include/ copied into thirdparty/tcc/:
    ./makev.bat -tcc bootstraps successfully end-to-end (previously
    failed at the intrin.h #include on the very first line of
    output).
  • ./v.exe run examples/hello_world.v succeeds with the resulting
    compiler.
  • ./v.exe test vlib/math/bits/ passes (exercises the
    $if msvc/$else branches these headers touch).
  • Reviewer's exact repro (#include <intrin.h> alone, tcc.exe -c)
    passes against the current stub; confirmed it fails against the
    earlier real-header revision.
  • Two rounds of an independent adversarial-review workflow run
    against this PR; the one confirmed finding (the dbghelp.h
    order-dependence gap above) is fixed and documented.
  • Not yet verified against thirdparty-windows-i386 — this PR only
    targets windows-amd64.

🧙 Built with WOZCODE

PythonWillRule and others added 2 commits September 26, 2026 22:21
vlang's vc/v_win.c bootstrap snapshot is always generated with -cc msvc,
so it unconditionally does #include <intrin.h> and #include <dbghelp.h>
under #ifdef _WIN32. This toolchain ships neither header, so building
vc/v_win.c directly with tcc.exe fails immediately, before any real code
is reached.

Both files are intentionally empty (just a header guard):
- Every call site for the MSVC intrinsics vlang's cgen can emit
  (_umul128, _udiv128, _addcarry_u64, _BitScanForward, _BitScanForward64)
  is wrapped in #if defined(_MSC_VER) at the C level, so under tcc those
  branches never compile - portable fallbacks run instead.
- include/winapi/winnt.h (pulled in by <windows.h>, included immediately
  before these headers) already provides working _BitScanForward,
  _BitScanForward64 and __faststorefence for this toolchain, via
  vlang-header-compat.patch. Redeclaring them causes a redefinition error.
- DbgHelp (SymInitialize, SymFromAddr, ...) is resolved dynamically via
  GetProcAddress at runtime, not through dbghelp.h's declarations.

Porting the real MinGW-w64 intrin.h was considered instead, but it pulls
in intrin-impl.h plus mmintrin.h/xmmintrin.h/emmintrin.h/immintrin.h,
none of which this bundle ships, for no functional benefit given the
above.

Co-Authored-By: WOZCODE <contact@withwoz.com>
The previous commit added empty intrin.h/dbghelp.h stubs, sufficient
only to satisfy vc/v_win.c's unconditional #include lines for vlang's
current bootstrap snapshot. Per this repo's own README ("copy the ported
headers into include/, small modifications sometimes needed"), use the
real mingw-w64 headers instead, so any other program that includes
these headers under this tcc gets working declarations, not a no-op.

Both compile cleanly under tcc as-is, once their small dependency chain
is also vendored:
- dbghelp.h needs psdk_inc/_dbg_LOAD_IMAGE.h and psdk_inc/_dbg_common.h
  (the latter needs pshpack4.h/poppack.h, the pack-pragma helpers).
- intrin.h has no unmet dependencies; its SSE/AVX-intrinsic branches are
  conditionally compiled and inactive here.

All six files are unmodified mingw-w64 runtime sources (public domain,
no copyright assigned), matching the existing include/winapi/*.h files
already vendored in this bundle from the same project.

Verified against vlang/v (checkout at commit c4998cf): a full
./makev.bat -tcc bootstrap succeeds, and `./v test vlib/math/bits/`
passes with the rebuilt compiler.

Co-Authored-By: WOZCODE <contact@withwoz.com>

@medvednikov medvednikov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed 65dc75a174e83652cab0b6f65c5700fc684759d9, without considering CI status or results.

One actionable finding (P2): intrin.h has an include-order-dependent missing-dependency failure. Details and a minimal reproduction are attached inline.

An important distinction: this does not establish a failure of the reported V bootstrap. The bundled include/_mingw.h defines __INTRIN_H_, so including the normal TCC/Windows headers first skips the entire new intrin.h body, not just its SSE/AVX branches. That can satisfy the bootstrap's include directive without demonstrating that the imported intrinsic declarations are usable.

I also checked the added DbgHelp dependency headers and the paired packing helpers; I did not identify another bundle-integration finding in that inspection.

Validation was source inspection of the PR, the bundled header guards/dependency paths, and relevant upstream sources. I did not run a Windows/TCC compilation, a V bootstrap, or the V test suite locally.

Comment thread include/intrin.h Outdated
@medvednikov correctly found that the ported real mingw-w64 intrin.h
can't actually work in this toolchain:

- include/_mingw.h unconditionally does `#define __INTRIN_H_` (its
  own line ~146), which is intrin.h's own header guard. Since
  <windows.h> (included immediately before intrin.h in vc/v_win.c)
  pulls in _mingw.h first, intrin.h's entire body was already skipped
  by its own guard - not just its SSE/AVX branches, as I'd claimed.
- Standalone (or any include order where _mingw.h hasn't run yet),
  intrin.h fails outright: it requires crtdefs.h and
  psdk_inc/intrin-impl.h, neither of which this bundle ships.
  Confirmed with the reviewer's exact repro
  (`echo '#include <intrin.h>\nint main(void){return 0;}' > t.c &&
  tcc.exe -c t.c` fails with "crtdefs.h not found"; an empty stub
  compiles it cleanly).

This toolchain's own _mingw.h is evidently patched to preempt real
intrin.h entirely, so porting it was the wrong move here - reverting
to the minimal empty stub, which has no such landmine regardless of
include order. dbghelp.h and its dependency chain are unaffected (no
finding raised there) and unchanged.

Co-Authored-By: WOZCODE <contact@withwoz.com>

@medvednikov medvednikov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rechecked the fix at 2a102c922b42aa793111e06d33c58f1e0ff17aee, without considering CI status or results.

The previous P2 finding is addressed. No new actionable correctness findings in the revised intrin.h.

The replacement is a dependency-free compatibility stub with its own TCC_INTRIN_H_SHIM guard. It no longer includes the missing crtdefs.h or psdk_inc/intrin-impl.h, and it does not depend on _mingw.h having already defined __INTRIN_H_. It preserves the intended no-op for the bootstrap's include directive without introducing declarations or definitions that could conflict with the bundled Windows headers. Its comments now explicitly describe the limited scope rather than claiming a full intrinsic implementation.

Validation: compiled the fetched 36-line header in isolation with GCC 14.2 on Linux using -std=c11 -Wall -Wextra -Werror -nostdinc and only the isolated header directory on the include path. Repeated inclusion passed in all four configurations: __INTRIN_H_ defined/undefined, each with and without _WIN32/_WIN64 defined. These are header self-containment checks, not Windows/TCC integration tests. I did not run the bundled Windows compiler, the actual windows.h include-order combinations, a V bootstrap, or the V test suite locally.

Non-blocking documentation note: please update the PR description, which still describes intrin.h as an unmodified real MinGW-w64 header with inactive SSE/AVX branches. That no longer matches the deliberately empty compatibility stub.

…l review

An adversarial review of this PR found: unlike include/intrin.h (an
empty stub with zero dependencies, genuinely order-independent),
dbghelp.h is the real mingw-w64 header and is NOT order-independent -
its dependency psdk_inc/_dbg_LOAD_IMAGE.h uses PSTR/PUCHAR/HANDLE/etc.
without defining or including them, relying on <windows.h> having run
first. Verified live: `#include <intrin.h>` then `#include <dbghelp.h>`
without windows.h first fails to preprocess
(psdk_inc/_dbg_LOAD_IMAGE.h:24: ';' expected (got 'PSTR')); the actual
vc/v_win.c order (windows.h, then intrin.h, then dbghelp.h) compiles
clean, so vlang's real bootstrap is unaffected.

Documenting this in dbghelp.h itself rather than vendoring more of
windows.h's typedef surface into _dbg_LOAD_IMAGE.h, which risks
conflicting redefinitions when combined with a real <windows.h>
inclusion and doesn't match this bundle's actual only consumer's
include order anyway.

Co-Authored-By: WOZCODE <contact@withwoz.com>
@quaesitor-scientiam

Copy link
Copy Markdown
Author

Ran an adversarial review pass on this PR (5 independent lenses, 3 adversarial refuters per candidate finding). One confirmed, real gap: dbghelp.h doesn't have the same order-independence property intrin.h's empty stub does - its dependency psdk_inc/_dbg_LOAD_IMAGE.h uses PSTR/PUCHAR/HANDLE/etc. without defining or including them, relying on <windows.h> having already run. Verified live: #include <intrin.h> then #include <dbghelp.h> without windows.h first fails (psdk_inc/_dbg_LOAD_IMAGE.h:24: ';' expected (got 'PSTR')); the actual vc/v_win.c order (windows.h, then intrin.h, then dbghelp.h) still compiles clean, so this doesn't affect the real build. Documented the requirement directly in dbghelp.h in da89255 rather than vendoring more of windows.h's typedef surface (which risks conflicting redefinitions and doesn't match this bundle's only actual consumer's include order anyway).

The other candidate findings from that review didn't survive adversarial verification, and I found no other guard-collision or missing-dependency issue beyond this one.

@quaesitor-scientiam

Copy link
Copy Markdown
Author

Thanks for the recheck. Updated the PR description to describe the actual current state (empty stub for intrin.h, real header + documented include-order requirement for dbghelp.h) rather than the abandoned real-header approach.

@JalonSolov

Copy link
Copy Markdown

Does this change also need to be made to windows-i386 branch?

@quaesitor-scientiam

Copy link
Copy Markdown
Author

Yes - checked before assuming: `thirdparty-windows-i386`'s `include/_mingw.h` predefines `_INTRIN_H` at the same spot (line 140 vs 146 on amd64), and neither `intrin.h` nor `dbghelp.h` exists on that branch either, so it has the identical gap this PR fixes.

Opened a companion PR: #98

quaesitor-scientiam pushed a commit to quaesitor-scientiam/tccbin that referenced this pull request Sep 28, 2026
Per an adversarial review of vlang#98 (2 findings, each confirmed by all
3 independent lenses):

- intrin.h cited "_mingw.h line ~146" for the __INTRIN_H_ guard, but
  that's the amd64 branch's line, carried over unedited from vlang#96.
  This branch's own line is 140. Dropped the specific number entirely
  (it will drift again the next time either branch's _mingw.h
  changes) in favor of pointing at the macro name to grep for.

- dbghelp.h claimed the windows.h -> intrin.h -> dbghelp.h include
  order "has been verified to build" - true on the amd64 sibling
  (a real forced-MSVC/TCC build was run for vlang#96), not true here: no
  i386 TCC toolchain or V build target was available to verify this
  branch, as vlang#98's own description already discloses. The claim as
  shipped would outlive that disclosure once the PR closes, so a
  future reader of just this file would take it as settled fact.
  Removed the claim and pointed at vlang#98 for the real status instead.

Co-Authored-By: WOZCODE <contact@withwoz.com>

@medvednikov medvednikov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the current six-file change at da89255a949156be032ee75372857bd2edf4898b, including the revised intrinsic shim and DbgHelp dependency/packing integration. CI status/results were excluded.

No new actionable correctness issue found in the header integration reviewed. The earlier intrinsic-header dependency finding remains fixed, and the description now accurately identifies the empty shim.

intrin.h uses its own TCC_INTRIN_H_SHIM guard and introduces neither external dependencies nor intrinsic declarations. In particular, it no longer relies on an earlier Windows/CRT header defining __INTRIN_H_ to hide missing includes. This is an include-compatibility shim, not a general implementation of MSVC intrinsics.

For DbgHelp, the added _dbg_LOAD_IMAGE.h and _dbg_common.h include chain is present, _mingw_unicode.h is an existing bundle dependency, and the new push/pop packing headers pair correctly around the minidump declarations. The common header's Git blob SHA (aa94da4a79260cc06e801c37d6343a3efbda5a48) exactly matches the upstream mingw-w64 file I fetched and the i386 companion PR. The _WIN64-conditional _IMAGEHLP64 selection preserves the architecture-specific aliases rather than forcing them on every target.

The added dbghelp.h comment correctly discloses that <windows.h> must precede it; this change does not make that header self-contained, and the intrinsic-shim self-containment check should not be presented as a DbgHelp integration check.

Local validation: 12 isolated Clang syntax/layout probes across i686 and x86_64 Windows targets, using the fetched shim/packing helpers' active contents, with __INTRIN_H_ defined/undefined and normal/RC_INVOKED/lint configurations. Repeated inclusion, four-byte packing, and restoration of incoming packing passed. The expected Clang warning about a packing helper deliberately changing alignment across an include was disabled (-Wno-pragma-pack); layout/restoration were checked with static assertions.

Limits: these small probes do not compile the entire bundled Windows header tree. I did not run Windows TinyCC, link a DbgHelp caller, execute a V bootstrap, or run V tests. No Windows interpreter or V compiler is installed locally, and direct checkout downloads fail DNS resolution. The author's end-to-end amd64 reports are not claimed as my own executions.

@quaesitor-scientiam

Copy link
Copy Markdown
Author

Thanks for the thorough re-review - appreciate the independent blob-SHA cross-check against the i386 companion and the Clang probes across both pointer widths.

Follow-up on the i386 side, in case useful context: #98 (the companion PR you cross-checked) went through its own adversarial review and picked up two comment-accuracy fixes (a stale line-number reference and an inherited "verified to build" claim that wasn't true for that branch - both fixed in 2893cc1). Pushing further to actually get a real i386 build running turned up something bigger and unrelated to either PR's header content: thirdparty-windows-i386's bundled tcc.exe is a much older build (0.9.27, stock 2017) than amd64's (0.9.28rc, a newer custom fork) and can't compile vc/v_win.c at all past a _Bool/C11-atomics line, even with every header gap patched. Opened that as #99 since it's a toolchain-provenance question, not a header fix. Also found and fixed one more small header gap along the way (winapi/psapi.h, missing entirely from i386) in #100.

None of that changes anything about this PR - just flagging in case the i386 toolchain-version question in #99 is relevant to how you'd want to sequence merging the i386-side PRs.

JalonSolov pushed a commit that referenced this pull request Sep 29, 2026
Ported from thirdparty-windows-amd64, where this file is a
pre-existing part of the base bundle (not something #96/#98 added).
It does not exist anywhere on thirdparty-windows-i386.

Confirmed via a real build: without this file, compiling vc/v_win.c
with this branch's tcc.exe fails at v_win.c:58 on
#include <psapi.h>. With it added, the build gets substantially
further (to v_win.c:682, an unrelated _Bool/_Atomic feature gap in
this branch's older 0.9.27 tcc.exe vs. amd64's 0.9.28rc build - see
#99, which this PR does not attempt to fix).

The ported file's one arch-sensitive spot (PSAPI_WORKING_SET_BLOCK's
VirtualPage bitfield width) already branches correctly on _WIN64,
which is unset for this branch's i386 target.

Co-Authored-By: WOZCODE <contact@withwoz.com>
@medvednikov
medvednikov merged commit dc80dc8 into vlang:thirdparty-windows-amd64 Sep 30, 2026
0 of 2 checks passed
@quaesitor-scientiam
quaesitor-scientiam deleted the fix-windows-intrin-dbghelp-headers branch October 5, 2026 03:18
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.

4 participants