Repository navigation
win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c - #96
Conversation
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
left a comment
There was a problem hiding this comment.
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.
@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
left a comment
There was a problem hiding this comment.
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>
|
Ran an adversarial review pass on this PR (5 independent lenses, 3 adversarial refuters per candidate finding). One confirmed, real gap: 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. |
|
Thanks for the recheck. Updated the PR description to describe the actual current state (empty stub for |
|
Does this change also need to be made to |
|
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 |
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
left a comment
There was a problem hiding this comment.
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.
|
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: 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. |
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>
dc80dc8
into
vlang:thirdparty-windows-amd64
Summary
vlang/v'svc/v_win.cbootstrap snapshot is always generated with-cc msvc(seevlang/v's.github/workflows/gen_vc_ci.yml), whichmakes its cgen emit unconditional
#include <intrin.h>and#include <dbghelp.h>under#ifdef _WIN32(seevlang/v'svlib/v/gen/c/cleanc.v, theg.ccompiler == 'msvc'branch). Thistoolchain ships neither header, so
./makev.bat's default TCC-firstbootstrap path fails immediately on a fresh Windows clone of
vlang/v,before reaching any real code:
This PR adds both headers:
include/intrin.h— an empty compatibility stub (see the file's owncomment for why: an earlier revision of this PR ported the real
mingw-w64 header, but
include/_mingw.hunconditionally#define __INTRIN_H_— that header's own guard — so with<windows.h>included first (the realvc/v_win.corder), its bodywas silently skipped entirely, and used standalone it failed outright
on missing
crtdefs.h/psdk_inc/intrin-impl.h, neither shipped inthis 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 callsite is wrapped in
#if defined(_MSC_VER)at the C level — and_BitScanForward/_BitScanForward64/__faststorefenceare alreadyimplemented for tcc in
include/winapi/winnt.hviavlang-header-compat.patch. So the stub costs nothing.include/dbghelp.h— the real mingw-w64 header (public domain, nocopyright assigned — same provenance as the
include/winapi/*.hfiles 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 helpersinclude/pshpack4.h/include/poppack.h. Unlikeintrin.h, thisone is NOT include-order-independent — its own top comment (added in
da89255) documents that it requires<windows.h>first, whichmatches
vc/v_win.c's actual order and is not a problem for thisbundle's only consumer.
This change is additive: it lets the
#includelines resolve, with norisk of redefinition (verified) or behavior change to existing code.
Test plan
vlang/vcheckout (commitc4998cf, later73956465)with this bundle's
include/copied intothirdparty/tcc/:./makev.bat -tccbootstraps successfully end-to-end (previouslyfailed at the
intrin.h#includeon the very first line ofoutput).
./v.exe run examples/hello_world.vsucceeds with the resultingcompiler.
./v.exe test vlib/math/bits/passes (exercises the$if msvc/$elsebranches these headers touch).#include <intrin.h>alone,tcc.exe -c)passes against the current stub; confirmed it fails against the
earlier real-header revision.
against this PR; the one confirmed finding (the
dbghelp.horder-dependence gap above) is fixed and documented.
thirdparty-windows-i386— this PR onlytargets
windows-amd64.🧙 Built with WOZCODE