Fix long double width on FreeBSD/PowerPC - #9148
Open
pkubaj wants to merge 1 commit into
Open
Conversation
set_arch_spec_power() sets long_double_width to 16*8 for every PowerPC
subarchitecture. That matches Linux, where long double is 128-bit IBM
double-double, but not FreeBSD, where long double on PowerPC is the same
as double -- with the exception of powerpc64le since FreeBSD 16.0, which
uses IEEE binary128.
Because the width does not match the host, verifying natively on
FreeBSD/powerpc64le aborts as soon as any tool configures itself:
--- begin invariant violation report ---
Invariant check failed
File: src/util/config.cpp:1132 function: set
Condition: ansi_c.long_double_width == sizeof(long double) * CHAR_BIT
Reason: long double width shall be equal to the system long double width
--- end invariant violation report ---
Abort trap (core dumped)
This is not hypothetical for a build either: the regression tests run the
freshly built goto-gcc, so the build itself fails.
Neither constant is right for FreeBSD, as the width depends on the
release:
FreeBSD 15.1, powerpc64le: sizeof(long double) * CHAR_BIT == 64
(__LDBL_MANT_DIG__ 53)
FreeBSD 16.0, powerpc64le: sizeof(long double) * CHAR_BIT == 128
(__LDBL_MANT_DIG__ 113, __LONG_DOUBLE_IEEE128__)
Take the width from the toolchain instead of hard-coding it, which is
exactly the quantity the invariant compares against and stays correct
across that transition. The override lives in configt::set() rather than
in set_arch_spec_power(), which only receives the subarchitecture and has
no way to know the target operating system; the neighbouring
macos/arm64 case already sets long_double_width the same way.
pkubaj
requested review from
kroening,
peterschrammel and
tautschnig
as code owners
August 3, 2026 06:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
set_arch_spec_power() sets long_double_width to 16*8 for every PowerPC subarchitecture. That matches Linux, where long double is 128-bit IBM double-double, but not FreeBSD, where long double on PowerPC is the same as double -- with the exception of powerpc64le since FreeBSD 16.0, which uses IEEE binary128.
Because the width does not match the host, verifying natively on FreeBSD/powerpc64le aborts as soon as any tool configures itself:
--- begin invariant violation report ---
Invariant check failed
File: src/util/config.cpp:1132 function: set
Condition: ansi_c.long_double_width == sizeof(long double) * CHAR_BIT
Reason: long double width shall be equal to the system long double width
--- end invariant violation report ---
Abort trap (core dumped)
This is not hypothetical for a build either: the regression tests run the freshly built goto-gcc, so the build itself fails.
Neither constant is right for FreeBSD, as the width depends on the release:
FreeBSD 15.1, powerpc64le: sizeof(long double) * CHAR_BIT == 64
(LDBL_MANT_DIG 53)
FreeBSD 16.0, powerpc64le: sizeof(long double) * CHAR_BIT == 128
(LDBL_MANT_DIG 113, LONG_DOUBLE_IEEE128)
Take the width from the toolchain instead of hard-coding it, which is exactly the quantity the invariant compares against and stays correct across that transition. The override lives in configt::set() rather than in set_arch_spec_power(), which only receives the subarchitecture and has no way to know the target operating system; the neighbouring macos/arm64 case already sets long_double_width the same way.