Skip to content

cpp/llvm: use selected LLVM metadata and qualify LLVM 22 - #27

Open
zhouguangyuan0718 wants to merge 6 commits into
goplus:mainfrom
zhouguangyuan0718:codex/windows-msvc-llvm21-interop-20260828
Open

cpp/llvm: use selected LLVM metadata and qualify LLVM 22#27
zhouguangyuan0718 wants to merge 6 commits into
goplus:mainfrom
zhouguangyuan0718:codex/windows-msvc-llvm21-interop-20260828

Conversation

@zhouguangyuan0718

@zhouguangyuan0718 zhouguangyuan0718 commented Aug 28, 2026

Copy link
Copy Markdown

Summary

  • use the stable llvm pkg-config alias for the Windows demangle bridge instead of a version-named package
  • leave LLVM version enforcement to the LLGo/toolchain setup that creates the alias
  • keep llvm-config --host-target, the selected Windows C++ ABI, ordered LLVM libraries, and the C ABI boundary unchanged
  • move repository qualification to LLVM 22 without depending on an open LLGo PR or a personal module replacement

LLVM 22 qualification

  • Linux and macOS build the exact merged LLGo revision 6fc2ef150f95d8b9331433f325fcb1b6ee5ad4e4 with the released github.com/xgo-dev/llvm v0.9.8, byollvm, and system LLVM 22
  • the workflow validates llvm-config major 22 and passes its exact C/C++/link flags to the full Go build; the final link closure contains LLVM 22 only
  • Windows downloads the official LLVM 22.1.8 MSVC development archive and verifies SHA-256 d96c2cc1736f4eb7fa43cb9bbdf56d93551a9ae0a9aadb9c99c3c3b2b712a234
  • a native Windows C++ harness compiles the checked-in bridge with LLVM 22 headers, links LLVMDemangle.lib, and executes Itanium, Microsoft, and Rust demangling checks
  • the downstream LLGo LLVM 21 prerequisite and final LLVM 22 PR provide the full Go declaration → C bridge Windows integration lanes after this version-neutral source change merges

Validation

Exact head bdf7a1381373d3b8fc679c32bfb02da227fd93a6 is clean and all four repository checks pass:

  • build
  • llgo-test (Ubuntu, LLVM 22)
  • llgo-test (macOS, LLVM 22)
  • Windows LLVM 22 demangle bridge

Local validation also passed:

  • GOWORK=off go test ./...
  • stable LLGo + released Go LLVM binding + LLVM 22.1.8 built successfully with dev,byollvm; go build -x contained LLVM 22 only
  • LLGo tests passed for ./c, ./c/math/rand, ./c/net, ./c/os, ./c/setjmp, ./c/time, ./cpp/std, and ./cpp/llvm
  • standalone bridge harness compiled, linked, and ran against LLVM 22.1.8 LLVMDemangle
  • workflow YAML parsed and git diff --check passed

@fennoai fennoai 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.

Code Review: Windows/MSVC/LLVM21 interop bindings

Solid, carefully-executed PR. The //go:build tags fully partition the platform space for every shared symbol I traced (LLGoPackage, Stdin/Stdout/Stderr, StatT, String, Errno, Long/Ulong), so no package ends up with a duplicate or missing definition on any platform. Struct layouts are backed by explicit size/offset tests, which I independently verified as correct: WSAData (400 on 386, 408 on x64), SockaddrStorage = 128, SockaddrIn6 = 28, SockAddr = 16, Hostent offsets, and the MSVC std::string layout (16 + 2×uintptr). The send/recv length parameter correctly uses c.Int on Winsock (vs size_t on POSIX), and the Freeaddrinfo return-type fix (void) matches the real C signature — no callers in the repo depended on the removed c.Int return.

Findings below are inline. A few lower-priority notes:

  • Bind/Connect signature divergence. On Windows (c/net/functions_windows.go) Bind takes *SockAddr, while the non-Windows net.go declares Bind(..., addr *SockaddrIn, ...). The *SockAddr form is arguably more correct, but the inconsistency means portable call sites can't share one signature. Consider a doc note or aligning the Unix side in a follow-up.
  • CanOnName field name in c/net/addrinfo_windows.go is a misspelling of the Winsock ai_canonname field. It deliberately mirrors the same (pre-existing) misspelling in c/net/net.go, so fixing it here alone would create a Windows/Unix API divergence — worth a coordinated rename across both files rather than a one-sided change.
  • CI caching. Each matrix leg rebuilds xgo-dev/llgo (pinned ref) from source with no actions/cache; caching keyed on the LLGo ref + OS + Go version would cut repeated cold compiles.

Comment thread .github/workflows/go.yml Outdated
- name: Set up LLGo dependencies
uses: ./.llgo/.github/actions/setup-deps
with:
llvm-version: '19'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] CI installs LLVM 19 but Windows llvm config requires llvm-21

This step installs llvm-version: '19', but cpp/llvm/config_windows.go resolves its flags via pkg-config --cflags llvm-21 and pkg-config --libs llvm-21. The Windows test step runs ./cpp/llvm, so if the LLVM-19 install doesn't provide an llvm-21 pkg-config file, the Windows demangle bindings will fail to configure/link (or silently resolve against a different LLVM). Please align the installed llvm-version with the llvm-21 package the config expects (or parameterize both from one source).

if value == nil {
t.Fatal("demangler returned nil")
}
defer c.Free(unsafe.Pointer(value))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Possible cross-CRT free of demangler heap pointer on Windows

The demangle wrappers return heap pointers that LLVM allocates internally (via LLVM's CRT malloc), and callers free them with c.Free, which maps to libc free. On Windows the bridge is compiled against the MSVC CRT and linked to LLVM's MSVC-built binaries, while the LLGo target uses its own C runtime. If the malloc LLVM used and the free behind c.Free resolve to different CRT heaps, this is a cross-heap free (heap corruption). Please confirm both sides resolve to the same CRT heap, or add a matching llgoLLVMDemangleFree(char*) wrapper compiled in demangle_windows.cpp so the free happens on LLVM's heap.

Comment thread c/net/net_windows.go

const (
InvalidSocket SocketT = ^SocketT(0)
SocketError = -1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P3] SocketError left untyped while InvalidSocket is typed

InvalidSocket is typed SocketT, but SocketError = -1 is untyped. It is the sentinel returned by the c.Int-returning calls (Bind, Connect, etc.), so consider SocketError c.Int = -1 for consistency and to avoid accidental comparisons against unrelated int types.

@zhouguangyuan0718
zhouguangyuan0718 force-pushed the codex/windows-msvc-llvm21-interop-20260828 branch from adc184c to 5762a8b Compare August 29, 2026 11:33
@zhouguangyuan0718 zhouguangyuan0718 changed the title c, cpp: add minimal Windows interop bindings for LLVM 21 cpp/llvm: select LLVM 21 on Windows Aug 29, 2026
@zhouguangyuan0718 zhouguangyuan0718 changed the title cpp/llvm: select LLVM 21 on Windows cpp/llvm: use selected LLVM metadata on Windows Sep 1, 2026
@zhouguangyuan0718
zhouguangyuan0718 force-pushed the codex/windows-msvc-llvm21-interop-20260828 branch from 1242f1d to a8f1f82 Compare September 1, 2026 05:16
@zhouguangyuan0718 zhouguangyuan0718 changed the title cpp/llvm: use selected LLVM metadata on Windows cpp/llvm: use selected LLVM metadata and qualify LLVM 22 Sep 1, 2026
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