Skip to content

Fix __int128_t redefinition in int128.h !CONFIG_INT128 fallback on Clang/GCC - #2360

Open
robertream wants to merge 1 commit into
unicorn-engine:masterfrom
robertream:fix-int128t-redefinition-clang
Open

Fix __int128_t redefinition in int128.h !CONFIG_INT128 fallback on Clang/GCC#2360
robertream wants to merge 1 commit into
unicorn-engine:masterfrom
robertream:fix-int128t-redefinition-clang

Conversation

@robertream

Copy link
Copy Markdown

Problem

Building QEMU's int128.h fails on Clang/GCC whenever the build reaches the
!CONFIG_INT128 fallback:

qemu/include/qemu/int128.h:150:16: error: typedef redefinition with different types
    ('Int128' (aka 'struct Int128') vs '__int128')
typedef Int128 __int128_t;

The fallback aliases the reserved builtin name __int128_t to struct Int128
so fallback code can name the type. That is only valid on compilers that do not
provide __int128_t as a builtin. On GCC/Clang the builtin always exists (when
128-bit ints are supported), so the alias is a redefinition error.

This bit two real setups:

  • Apple clang on arm64 (macOS), and
  • the Rust unicorn-engine-sys crate's vendored build (its cmake path ends up
    without CONFIG_INT128, so it compiles the fallback — and fails on any modern
    clang/gcc).

#2251 added the current guard #if !(defined(_MSC_VER) && defined(__clang__)),
but that only covers clang-cl; regular Clang/GCC still hit the redefinition.

Fix

Gate the alias on !defined(__SIZEOF_INT128__). __SIZEOF_INT128__ is the standard
macro that is defined iff the compiler provides the 128-bit builtin, so:

  • GCC/Clang (incl. clang-cl): builtin present → alias skipped (uses the builtin) ✅
  • MSVC: no builtin → alias emitted (as before) ✅

This subsumes #2251 and fixes the general case.

Validation

  • tests/regress/int128_redefinition.c — a self-contained reproduction of the
    fallback construct. It fails to compile with the old guard on any
    __int128-capable compiler and compiles cleanly with the fix (verified on Apple
    clang / arm64, producing the exact error above pre-fix).
  • .github/workflows/int128-regression.yml — compiles + runs that test on
    macos-14 (Apple Silicon, arm64 clang), macos-13 (Intel) and Linux.

Why a new job: existing CI never exercises this fallback on arm64 clang — the
C-library CI builds on macos-14 via cmake with CONFIG_INT128 defined (native
path, fallback not compiled), and the Rust-crate CI (Crate-publishing.yml) does
not run on Apple Silicon.

Happy to drop the test/CI or fold it into an existing workflow if maintainers prefer.

…ang/GCC

The struct-based fallback aliases the reserved builtin name __int128_t to
`struct Int128` so fallback code can name the type. That is only valid on
compilers that do NOT provide __int128_t as a builtin; on GCC/Clang it is a
"typedef redefinition with different types ('Int128' vs '__int128')" error
whenever a build reaches this fallback. It bit real Clang builds — Apple clang
on arm64, and the Rust `unicorn-engine-sys` crate's vendored build.

PR unicorn-engine#2251 guarded this only for clang-cl (`_MSC_VER && __clang__`). Gate instead
on `!defined(__SIZEOF_INT128__)` — the standard macro that is defined iff the
compiler provides the 128-bit builtin — which correctly skips the alias for all
GCC/Clang (including clang-cl) and keeps emitting it for MSVC, subsuming unicorn-engine#2251.

Add tests/regress/int128_redefinition.c reproducing the exact fallback construct
(fails to compile with the old guard on any __int128-capable compiler, compiles
with the fix), and a CI workflow compiling it on macos-14 (Apple Silicon, arm64
clang), macos-13 (Intel) and Linux. Existing CI never covers this: the C build
on macos-14 uses cmake with CONFIG_INT128 defined (native path, fallback not
compiled), and the Rust-crate CI does not run on Apple Silicon.
@wtdcode

wtdcode commented Jul 6, 2026

Copy link
Copy Markdown
Member

Hi please note our PR should go against the dev branch.

Also tests go to tests/unit.

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.

2 participants