Skip to content

[types] Keep MinGW's x87 long double and spell it exactly in exported C - #1332

Merged
gmh5225 merged 1 commit into
devfrom
claude/mingw-record-abi
Oct 18, 2026
Merged

gmh5225 merged 1 commit into
devfrom
claude/mingw-record-abi

Conversation

@gmh5225

@gmh5225 gmh5225 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Summary

A MinGW program's long double is the x87's: 16 bytes on x64, and on x86 12 bytes aligned to four, where a double aligns to eight. Local types read every Windows program under Microsoft's ABI, whose long double is a double. Such members were kept as raw bytes, and a declared long double was 8 bytes.

MinGW's record ABIs (RecordABIs.def)

  • mingw-x64 and mingw-x86: Microsoft's records with the x87's long double.
  • A new LongDoubleAlign column gives x86's alignment of four.
  • A new Library column names the ABI whose header libraries a program joins, so MinGW programs still join the Windows libraries.

Which programs get it (recordABIOf, one place)

  • A Windows program whose own sections hold DWARF takes MinGW's ABI for its architecture. MinGW's GCC and Clang write that DWARF; Microsoft's compilers never do.
  • If the DWARF's own long double base type is 8 bytes, the program stays Microsoft's. clang-cl with -gdwarf is such a case (dwarfLongDoubleBytes).
  • A stripped MinGW program tells nothing of its compiler and stays Microsoft's.

Local types read that DWARF where no PDB describes the program; before, such a program had no types of its own ("none").

  • The session reads nothing else of that DWARF: names, variables and decompiled output are unchanged.
  • A load that kept no copy of the file reads none, as before.
  • Go's Windows programs hold DWARF too, so their types now read as well. Go has no long double.

Exported C has the same layout on every compiler

  • C has no long double that every compiler makes the same size. Outside signatures, the portable and Windows spellings now name the program's long double neverd_long_double_<n>.
  • The prelude declares that name as the compiler's own long double where __SIZEOF_LONG_DOUBLE__ is <n>. Elsewhere it is that many bytes, aligned as the program aligns them; for 8 bytes it is a double, which MSVC's long double is.
  • So a MinGW program's records compile to their layout under MSVC, and an MSVC program's under MinGW. Before, the size checks failed there.
  • Signatures keep long double, which the target's convention passes. The keywords spelling is the target's own.
  • The C parser reads the name back as the long double, and refuses it in a program whose long double has another size.
  • Python and Rust already rendered it as aligned bytes.

The checker's new mingw-x64 and mingw-x86 rows compile the program's C with MinGW's compiler, and the portable and Windows spellings with MSVC's too. The Windows spelling of every Windows row is now compiled by both Windows compilers. Rust runs for x86_64-pc-windows-gnu and i686-pc-windows-gnu, which the fetch script now installs.

Verification

  • SessionCAPITest.MinGWProgramsKeepTheX87LongDouble loads three images of the new mingw_types.c fixture, built as it says:

    • MinGW x64 (mingw-x64): member at 16, 16 bytes;
    • MinGW x86 (mingw-x86): member at 4, 12 bytes, the double at 16;
    • clang-cl with -gdwarf (microsoft): member at 8, 8 bytes.

    Each reads its types from its DWARF and joins the Windows libraries.

  • check_type_renders.py over records and a typedef holding long doubles, beside a double, a long long and a function pointer taking one, under every data model and record ABI pair: microsoft LLP64 and ILP32, mingw-x64, mingw-x86, itanium, apple-arm64, i386-sysv, android-i386 and aapcs32. None fails; Lua is skipped, as it is not installed here.

    • Newly checked: the MinGW rows' C on MSVC's compiler, every Windows row's Windows spelling on MinGW's, and Rust for x86_64-pc-windows-gnu and i686-pc-windows-gnu.
  • Each fixture's header compiles with its size and offset checks under clang for MSVC x86 and x64, MinGW x86 and x64, Linux i686, x86-64 and AArch64, and macOS arm64, in both spellings. 64-bit layouts were compiled for 64-bit targets only.

  • Tests: TypeParse.ExactLongDoublesReadBackAsTheProgramsOwn, TypeRender.RecordLongDoublesAreAsLargeOnEveryCompiler and the MinGW layouts in TypeParse/LocalTypes. NeverDTypesTests (123) and NeverDSessionCAPITests (172) pass, with the kernel inputs.

  • The style check passes.

Known failures and limitations

  • The Windows user libraries and the default fixture fail 3 checks, all in the new MinGW compile of their Windows spelling: redefinition of 'tagLC_ID', 'threadlocaleinfostruct' and 'localeinfo_struct'.
    • MinGW's <stdint.h> brings in its CRT's corecrt.h, which defines these records. The header defines them again.
    • This was already so before this change; nothing compiled these headers with MinGW's compiler until now. The next change addresses it: C library types taken from the system's headers.
  • A stripped MinGW program stays Microsoft's: nothing tells its compiler.
  • Cygwin's LP64 programs are not told apart.

A MinGW program's long double is the x87's, 16 bytes on x64 and on x86 12
aligned to four, which Microsoft's ABI, under which every Windows program's
types read, does not hold: its DWARF's long double members read as bytes,
and a declared long double was eight.  The record ABIs gain MinGW's, with
a column for x86's alignment and one naming the ABI whose header libraries
a program joins.  A Windows program whose own sections hold DWARF, which
MinGW's compilers write, takes them unless the DWARF's long double is a
double, as clang-cl's is; its types read from that DWARF where no PDB
describes it.

C spells no long double every compiler makes as large.  Outside
signatures, the portable and Windows spellings name the program's
neverd_long_double_<n>, which the prelude declares as the compiler's long
double where it is as large and elsewhere as bytes aligned as the
program's, and which the C parser reads back.  The checker compiles the
Windows spelling with both Windows compilers, and MinGW's rows with MSVC's
too.
@gmh5225
gmh5225 merged commit 87c75c7 into dev Oct 18, 2026
6 of 22 checks passed
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