ADR 0025: Pin the native reference toolchain to LLVM 23¶
Status¶
Proposed. It takes effect when the maintainer accepts the toolchain bump into
develop. The first full batch run on that commit is the Linux qualification.
Context¶
Ludus pins one LLVM major for native compilation, formatting, clang-tidy, the
static analyzer and sanitizers (config/tool_versions.json). Scripts and CMake
gates read the major from minimum.clang. Copies that cannot read that file
must agree with it, and test_ci.ToolchainPinTests checks them.
LLVM 18 stopped working on current macOS hosts:
- On macOS 26 and newer, compiler-rt before 22.1.3 hangs (ASan) or crashes
(TSan) before
main. The macOS sanitizer runtimes section describes the cause. Thanks to Andrew Haberlandt for the upstream fix, llvm/llvm-project#182943, which uses_dyld_get_dyld_header()and was backported to LLVM 22.1.3. - Clang 18 cannot compile against the macOS 27 SDK, which current Command Line
Tools select by default: the SDK's math headers need a
NANdefinition that Clang 18 lacks.
We measured LLVM 22.1.8 and 23.1.3 on an Apple M5 running macOS 26.6 with SDKs 26.5 and 27.0:
| LLVM 22.1.8 | LLVM 23.1.3 | |
|---|---|---|
| ASan+UBSan and TSan start-up, macOS 26.6 | passes (SDK 26.5) | passes 10 of 10 runs (SDK 26.5 and 27.0) |
| macOS 27 SDK | libc++ <cfloat> is empty after <cmath> (C++23), so Catch2 fails |
init and full build succeed |
| New compiler warnings | -Wc2y-extensions at every Catch2 TEST_CASE |
one -Wunused-but-set-global |
| clang-format changes | 14 files | 15 files |
| clang-tidy configuration | valid | hicpp-exception-baseclass removed |
macos-clang-asan-ubsan tests |
81 of 83 | 81 of 83 (same two, neither caused by the sanitizers) |
The libc++ 22 failure comes from libc++'s float.h wrapper. It sets its include
guard on the SDK's partial __need_infinity_nan include. LLVM 23 removes that
wrapper; thanks to Ian Anderson, llvm/llvm-project#175849.
The init SDK probe now also checks <cfloat> after <cmath>, whichever LLVM is pinned.
Decision¶
Pin LLVM 23.1.x, at least 23.1.3, for every native tool. The pin covers
tool_versions.json minimums, the ludus-tools mirror, Conan profiles, example
presets, the Behavior native compiler major, CI, the devcontainer and setup.
Managed Conan moves to 2.33.0, the first release whose settings.yml lists clang 23.
- Ubuntu 24.04. Its archive stops before LLVM 23, so CI, the devcontainer and
init register the pinned
llvm-toolchain-<codename>-23suite from apt.llvm.org. The archive key is committed asconfig/apt/apt.llvm.org.asc, andscripts/python/llvm_apt_source.pychecks its fingerprint (6084F3CF814B57C1CF12EFD515CF4D18AF4F7421) before apt trusts it. Setup never downloads a key. Thanks to the LLVM project for the apt.llvm.org packages. - macOS. Setup and CI install
llvm@23andlld@23; Homebrew packages LLD separately. Until Homebrew versions LLVM 23, both are aliases of the unversioned formulae. Init therefore rejects an alias thatbrew upgrademoved to another major. - clang-tidy.
hicpp-exception-baseclassis gone; its successor,bugprone-std-exception-baseclass, comes in throughbugprone-*.portability-avoid-pragma-oncecontradicts the#pragma onceconvention and is disabled.bugprone-signed-bitwiseis disabled: on macOS it reported 348 sites, and the 49 left after ignoring positive literals were all integer promotion of unsigned bytes or C API flag macros defined as signedint. Other new findings are fixed or suppressed at the site with a reason. - Formatting. clang-format 23 differs from 18 on a few constructs, so the repository is reformatted in a single commit alongside the pin.
Consequences¶
- Local macOS 26 developers can run the sanitizer presets and use the default SDK.
- Ubuntu hosts depend on a third-party apt source. apt.llvm.org serves only the newest 23.1.x build, so the exact patch version follows its releases.
- Installed SDKs and game projects record the exact compiler. They must be rebuilt or repaired after the bump. CI compiler and Conan caches start cold.
- Behavior native profiles are admitted per compiler major, so their qualification evidence must be re-run with Clang 23.
config/build_budget.jsonkeeps its LLVM 18 measurements until an idle host re-measures them.- Not measured before this decision: Linux builds, tests and tidy with Clang 23; Vulkan and Wayland translation units; the Qt editor; the SDK consumer; and the devcontainer image build. The first CI run of the bump qualifies them.