Skip to content

fix windows build errors due to compiler bug#6402

Merged
anonrig merged 2 commits intomainfrom
yagiz/fix-workerd-npm-compiler-issues
Mar 25, 2026
Merged

fix windows build errors due to compiler bug#6402
anonrig merged 2 commits intomainfrom
yagiz/fix-workerd-npm-compiler-issues

Conversation

@anonrig
Copy link
Copy Markdown
Member

@anonrig anonrig commented Mar 24, 2026

listenOnSockets() uses goto to jump past variable declarations inside a
switch, then co_awaits at the end of the function. This goto-inside-
coroutine pattern creates a pathological CFG that crashes clang-cl 20's
jump-threading and correlated-propagation optimizer passes on Windows
(SIGSEGV / 0xC0000005), breaking the release build intermittently since
at least 2026-03-11.
Extract the switch into a non-coroutine helper Server::parseSocketType()
that returns kj::Maybe. listenOnSockets() calls it and
uses KJ_IF_SOME/continue instead of goto, giving the optimizer a clean
CFG.

@anonrig anonrig requested a review from fhanau March 24, 2026 19:41
@anonrig anonrig requested review from a team as code owners March 24, 2026 19:41
@anonrig anonrig requested a review from gabivlj March 24, 2026 19:41
@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 24, 2026

Line 626 still says egressMappings (the old field name). This is a minor stale comment but not something I'd flag as actionable per review policy (it's a comment reference, not logic).

Now let me assess the overall change:

Summary: This PR moves EgressMapping and EgressState from container-client.h into container-client.c++ using a pimpl pattern, to avoid exposing kj::OneOf<kj::CidrRange, kj::String> and kj::Vector<EgressMapping> to translation units that include the header. The motivation is a clang-cl compiler crash on Windows.

Analysis:

  1. The pimpl is correctly implemented:

    • EgressState is forward-declared in the header, stored via kj::Own<EgressState>.
    • EgressMapping is forward-declared in the header (only used in upsertEgressMapping parameter).
    • Both structs are fully defined in the .c++ file.
    • The destructor is defined in .c++ (not inline in the header), so kj::Own<EgressState> can correctly destroy the incomplete type.
    • egressState is initialized in the constructor with kj::heap<EgressState>().
  2. All access sites correctly changed from egressMappings to egressState->mappings.

  3. The #include <kj/cidr.h> was correctly removed from the header since kj::CidrRange is no longer needed there.

  4. No behavioral changes — purely a refactoring to move types behind the compilation boundary.

  5. No backward compatibility concerns — this is all internal implementation.

  6. No security concerns.

  7. The only minor nit is the forward declaration of EgressMapping in the header at line 170, which is needed because upsertEgressMapping(EgressMapping mapping) takes it by value. This works because the function is only declared in the header, not defined — the compiler only needs the complete type at the definition site (in .c++). This is correct C++.

This is a clean, well-motivated refactoring with no issues.

LGTM

github run

@anonrig anonrig requested a review from jasnell March 24, 2026 19:46
@anonrig
Copy link
Copy Markdown
Member Author

anonrig commented Mar 24, 2026

This is not a complete fix. I'll push one more commit.

@anonrig anonrig changed the title container: hide EgressMapping from container-client.h to fix Windows fix windows build errors due to compiler bug Mar 24, 2026
@anonrig
Copy link
Copy Markdown
Member Author

anonrig commented Mar 24, 2026

/bigbonk review and roast this pr

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

Two commits, both addressing clang-cl 20 optimizer crashes on Windows:

Commit 1 (container-client pimpl): Moves EgressMapping and EgressState behind a pimpl boundary in container-client.c++. Correctly implemented: forward declarations in the header, full definitions in the .c++ file, destructor defined in the .c++ file, kj::Own<EgressState> initialized with kj::heap<EgressState>(). All access sites updated consistently. The #include <kj/cidr.h> removal from the header is correct since kj::CidrRange is no longer needed there.

Commit 2 (listenOnSockets goto removal): Extracts the socket-type switch into parseSocketType(), a non-coroutine helper returning kj::Maybe<SocketTypeConfig>. This eliminates the goto-over-initialization inside the coroutine that was triggering the clang optimizer crash. The SocketTypeConfig struct fields have the same default values as the old local variables (0, default-constructed reader, nullptr), so behavior is preserved for all three socket types including TCP.

One minor nit posted inline (double-checking the Maybe). No correctness, safety, or compatibility issues.


This review was generated by an AI assistant and may contain errors. Please verify any suggestions independently.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 24, 2026

Review posted on PR #6402 with approval. Summary of findings:

  • Commit 1 (container-client pimpl): Clean, correct implementation. Forward declarations in the header, full definitions in the .c++ file, proper kj::Own<EgressState> initialization. All access sites updated consistently.

  • Commit 2 (listenOnSockets goto removal): Correctly extracts the socket-type switch into a non-coroutine helper parseSocketType() returning kj::Maybe<SocketTypeConfig>. Eliminates the goto-over-initialization pattern that was causing the clang-cl optimizer crash. Behavior is preserved — the SocketTypeConfig struct defaults match the old local variable defaults exactly.

  • One minor inline nit: The == kj::none + KJ_ASSERT_NONNULL pattern double-checks the Maybe. Idiomatic KJ would use KJ_IF_SOME, but given the long loop body and existing patterns in the file, the current form is reasonable.

  • No correctness, safety, or compatibility issues found.

github run

@anonrig anonrig merged commit 5d002a6 into main Mar 25, 2026
25 of 27 checks passed
@anonrig anonrig deleted the yagiz/fix-workerd-npm-compiler-issues branch March 25, 2026 15:58
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.

3 participants