From 3798382ea015dc3f886c0e41684270acfff56925 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 3 Aug 2026 07:04:32 +0000 Subject: [PATCH] go-pathrs: don't derive ProcBase from the C enum cbindgen v0.29.3 emits the C23 fixed-type enum syntax for sized enums[1], so in C23 mode pathrs_proc_base_t names the enum rather than uint64_t. CGo maps a C enum to a *signed* Go type, so none of the open-coded ProcBase constants fit in it any more and the package stops compiling: > internal/libpathrs/libpathrs_linux.go:228:22: cannot use > 0xFFFF_FFFE_7072_6F63 (untyped int constant 18446744067006164835) as > ProcBase value in constant declaration (overflows) Our own tree does not show this, because CI is pinned to cbindgen v0.29.2[2], so the checked-in header and the release tarball still typedef uint64_t. Fedora (and presumably other distros) do hit it, because they build the crate with `cargo-c`, which generates the header with its own cbindgen. Fedora rawhide has cbindgen v0.29.4 and gcc 16, which defaults to C23, so libpathrs-devel-0.2.5-2.fc45 ships the C23 spelling and every Go consumer of it fails to build. The workaround there is to force the older language version with `CGO_CFLAGS=-std=gnu17`. Declare the type as plain uint64 instead, which is what the docstring already promises. That also holds up under the direction discussed in [1], where the #if guards would be dropped in favour of an opt-out and the enum spelling would become unconditional. Nothing else has to change: the values were already converted with C.pathrs_proc_base_t() at each call site, and init() already reads the C constants through int64 temporaries because CGo signs those too. [1]: https://github.com/mozilla/cbindgen/pull/1156 [2]: https://github.com/cyphar/libpathrs/pull/383 Signed-off-by: Martin Pitt --- go-pathrs/internal/libpathrs/libpathrs_linux.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/go-pathrs/internal/libpathrs/libpathrs_linux.go b/go-pathrs/internal/libpathrs/libpathrs_linux.go index d610a3be..cceb20c0 100644 --- a/go-pathrs/internal/libpathrs/libpathrs_linux.go +++ b/go-pathrs/internal/libpathrs/libpathrs_linux.go @@ -217,7 +217,15 @@ func InRootHardlink(oldRootFd uintptr, oldPath string, newRootFd uintptr, newPat } // ProcBase is pathrs_proc_base_t (uint64_t). -type ProcBase C.pathrs_proc_base_t +// +// Spelled out rather than taken from C.pathrs_proc_base_t, because cbindgen +// since v0.29.3 emits the C23 fixed-type enum syntax for pathrs_proc_base_t, +// and in C23 mode that makes the typedef name the enum rather than uint64_t. +// CGo maps a C enum to a *signed* Go type, so none of the constants below fit +// in it and the package stops compiling. Every compiler defaulting to C23 +// (gcc >= 15) is affected. The values are converted back at each call site +// anyway, so nothing else has to know which spelling the header uses. +type ProcBase uint64 // FIXME: We need to open-code the constants because CGo unfortunately will // implicitly convert any non-literal constants (i.e. those resolved using gcc)