Repository navigation
[M2-PART-01 fix] Explicit integer-to-Scalar conversion for the macOS P0 toolchain - #82
Merged
Merged
Conversation
…P0 toolchain The macOS Intel (macos-14, AppleClang 15) lane of the M2-PART-01 merge run (37640282584) failed to build particles_tests.cpp: no matching conversion for static_cast from 'const std::uint32_t' to 'laige::fpx16_16' Root cause: static_cast<Scalar>(u32) with Scalar = fpx16_16 relies on the C++17 single-member-aggregate parenthesized-initialization corner (the cast behaves like fpx16_16(u32), aggregate-initializing raw from the int32 conversion). g++ 16, Linux clang 22, MSVC 2022, and AppleClang 16 (macos-15) all accept it; AppleClang 15 (the macOS-14 P0 toolchain) rejects it. The macOS arm64 lane passing in the same run while Intel failed confirms the compiler-version split. Fix: replace the aggregate cast with an explicit per-backend construction (a private ParticleSystem::fromInt and the test's oracle mirror sampleFromInt): the fpx branch uses the aggregate brace init (the house idiom, e.g. fpx16_16.h itself), the fp32 branch a plain int32->Scalar static_cast. The values are identical (exact on both backends: u < 2^24), so the determinism contract and the pinned KAT hashes are unchanged (verified: the particles-determinism fnv1a lines are bit-identical before/after). No public API change (private member only — laige-api.json regenerated and unchanged: 1410 symbols / 41 headers; api-real-tree green). All six local trees warning-clean + full ctest green (115/115, 115/115, 104/104, 115/115, 112/112, 112/112); lints green.
The first fix left the fp32 branch of fromInt/sampleFromInt as a plain statement AFTER the if-constexpr (no else), so it was still instantiated for the fpx backend — and it carries the same int32->fpx16_16 cast AppleClang 15 rejects (the PR-lane macOS Intel job 112876659688 failed on exactly that line). With the else the discarded branch is not instantiated: the fpx backend only ever instantiates the aggregate brace init, the fp32 backend only the int32->Scalar standard conversion. KAT unchanged (bit-identical particles-determinism lines); all six local trees warning-clean + full ctest green (115/115, 115/115, 104/104, 115/115, 112/112, 112/112); lints green; laige-api.json unchanged (private member only).
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.
M2-PART-01 fix · AppleClang (macOS-14 P0) rejects the fpx16_16 aggregate cast
Root cause. The macOS Intel lane (macos-14, AppleClang 15) of the M2-PART-01 merge run (37640282584) failed at Build:
static_cast<Scalar>(u)withScalar = fpx16_16compiles because of the C++17 single-member-aggregate parenthesized-initialization corner: the functional cast behaves likefpx16_16(u), aggregate-initializingrawfrom theu32 → int32_tconversion. g++ 16, Linux clang 22, MSVC 2022, and AppleClang 16 (macos-15) all accept the corner; AppleClang 15 rejects it. The run's split — macOS arm64 green, macOS Intel red — confirms the compiler-version boundary (not a code-path difference).Fix. Replace the aggregate cast with an explicit per-backend construction — the values are identical, so the determinism contract is untouched:
particles.h— new privateParticleSystem::fromInt(u32): the fpx branch uses the aggregate brace init (the house idiom —fpx16_16.hitself constructsfpx16_16{raw}throughout), the fp32 branch a plainint32 → Scalarstatic_cast.sampleScalarnow builds both operands viafromInt.particles_tests.cpp— the oracle mirrorsampleFromInt<Backend>(the oracle must follow the engine's sample path exactly).Exactness:
u < 2^24on both backends — fpx raw units exact; the fp32 24-bit mantissa represents every integer below 2^24 exactly.Verification.
particles-determinismlines are bit-identical before/after (fpx16_16 … fnv1a=0x2f87b731a5186d05,fp32_pinned … fnv1a=0xd37fb69c51a30681) — the sample path's values did not move.laige-api.jsonregenerated (private member only — unchanged: 1410 symbols / 41 headers);api-real-tree/api-check-fresh,tools/laige-include-lint,tools/laige-determinism-lintgreen.ci:macoslabel applied so this PR's lane runs the macOS lanes and proves the fix before merge.Scope. Two files, the exact failing construct only; no public API change, no behavior change, no doc change (the header comment records the toolchain constraint at the site).