Skip to content

go-pathrs: fix build failure with Clang - #410

Open
AkihiroSuda wants to merge 1 commit into
cyphar:mainfrom
AkihiroSuda:fix-401
Open

go-pathrs: fix build failure with Clang#410
AkihiroSuda wants to merge 1 commit into
cyphar:mainfrom
AkihiroSuda:fix-401

Conversation

@AkihiroSuda

@AkihiroSuda AkihiroSuda commented Aug 25, 2026

Copy link
Copy Markdown

The PATHRS_PROC_* values are defined in <pathrs.h> as an enum with values that are too large to fit in an int, and CGo's interpretation of their signedness turns out to be compiler-dependent: GCC hands them to us as implicitly-converted (negative) signed constants, while Clang gives us the actual unsigned values. Our sanity check in init() only handled the GCC behaviour (by assigning them to an int64), so builds using Clang failed with

  libpathrs_linux.go:256:32: cannot use (_Ciconst_PATHRS_PROC_ROOT)
    (untyped int constant 18446744067006164835) as int64 value in variable
    declaration (overflows)

Neither int64 nor uint64 can hold the constant with both compilers. However, Go constant expressions are arbitrary-precision and bitwise operations on negative constants operate on their infinite two's complement representation, so masking off the low 64 bits gives us the same uint64 value regardless of which compiler CGo used.

Note that this only affected the internal cross-check of the values (the constants themselves are open-coded on the Go side), so no user-visible behaviour changes -- but the package could not be built at all with Clang.

Also add a CC={gcc,clang} dimension to the Go smoke-test matrix so this doesn't regress. CC is only set for the smoke-test step so that we don't change how libpathrs itself is built.

Fixes #401

Assisted-by: Claude Opus 5


Tested with gcc 15.2.0 and clang 21.1.8 (Ubuntu 26.04, go 1.26.7) locally.

The PATHRS_PROC_* values are defined in <pathrs.h> as an enum with values
that are too large to fit in an int, and CGo's interpretation of their
signedness turns out to be compiler-dependent: GCC hands them to us as
implicitly-converted (negative) signed constants, while Clang gives us the
actual unsigned values. Our sanity check in init() only handled the GCC
behaviour (by assigning them to an int64), so builds using Clang failed with

  libpathrs_linux.go:256:32: cannot use (_Ciconst_PATHRS_PROC_ROOT)
    (untyped int constant 18446744067006164835) as int64 value in variable
    declaration (overflows)

Neither int64 nor uint64 can hold the constant with both compilers. However,
Go constant expressions are arbitrary-precision and bitwise operations on
negative constants operate on their infinite two's complement representation,
so masking off the low 64 bits gives us the same uint64 value regardless of
which compiler CGo used.

Note that this only affected the internal cross-check of the values (the
constants themselves are open-coded on the Go side), so no user-visible
behaviour changes -- but the package could not be built at all with Clang.

Also add a CC={gcc,clang} dimension to the Go smoke-test matrix so this
doesn't regress. CC is only set for the smoke-test step so that we don't
change how libpathrs itself is built.

Fixes cyphar#401

Assisted-by: Claude Opus 5
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

CGO/Clang Build failure

1 participant