Skip to content

fix: raise Clang constexpr budget to build pyarts with Clang 23 - #1195

Merged
riclarsson merged 2 commits into
atmtools:mainfrom
olemke:fix-libcxx23-constexpr-budget
Oct 20, 2026
Merged

riclarsson merged 2 commits into
atmtools:mainfrom
olemke:fix-libcxx23-constexpr-budget

Conversation

@olemke

@olemke olemke commented Oct 16, 2026

Copy link
Copy Markdown
Member

Summary

ARTS no longer builds with Clang 23: auto_isotopologues.h spells each of its 340 entries as .spec="H2O"_spec, so every TU that includes isotopologues.h resolves all species names at compile time with a linear constexpr scan over 120+120 string_views. That costs about 1.09M steps, just past Clang's default -fconstexpr-steps=1048576, and the build dies with "constexpr evaluation hit maximum step limit" in eight TUs. The Clang limit itself is unchanged -- libc++ 23 rewrote std::__find to route through __find_if with a generic lambda and nested std::__invoke calls, raising the cost of identical code by ~41% (0.78M to 1.09M steps). This branch gives Clang the headroom it needs and unblocks Clang 23 in the macOS dev environment.

Changes

  • CMakeLists.txt: append -fconstexpr-steps=4000000 to CMAKE_CXX_FLAGS in the existing Clang branch, alongside -stdlib=libc++. The value is ~3.7x the measured cost, enough for the species list to grow several times over while still stopping a runaway constexpr loop quickly. GCC's equivalent -fconstexpr-ops-limit default (33.5M) and MSVC's /constexpr:steps default (100M) already cover this, so neither compiler is touched.
  • environment-dev-mac.yml: raise the clangxx upper bound from <23 to <24 so conda can solve against the Clang 23.x series already in use on macOS workstations.
  • src/core/spec/make_species.cc: document why the generator keeps emitting the "_spec" literal instead of the apparently cheaper SpeciesEnum::<name> form. The enumerator form does remove the constexpr lookup entirely, but it makes GCC 16.2.0 crash with an internal compiler error -- a segfault in the recursive garbage-collector marking of gt_ggc_mx_lang_tree_node -- while compiling src/python_interface/py_predefined.cpp, the heaviest binding TU in the build. It reproduces on every Linux GCC builder. The comment is there so the "optimisation" does not come straight back.
  • No generated output changes and no behaviour changes: the regenerated header is byte-identical to the one on main, and the only cost is a little extra constexpr work in the affected Clang TUs -- work GCC has always paid.

auto_isotopologues.h spells every entry as `.spec="H2O"_spec`, so each TU
that includes isotopologues.h resolves all 340 species names at compile
time with a linear constexpr scan over 120+120 string_views.  That is
about 1.09M steps for the array, just past Clang's default
-fconstexpr-steps=1048576, so building pyarts fails with "constexpr
evaluation hit maximum step limit".

The limit itself is unchanged in Clang 23; libc++ 23 rewrote std::__find
to route through __find_if with a generic lambda and nested std::__invoke
calls, which raised the cost of the same code by ~41% (0.78M -> 1.09M
steps, measured with only that header swapped).

Emitting the enumerator instead of the literal does remove the lookup,
but it makes GCC 16.2.0 crash with an internal compiler error -- a
segfault in the recursive garbage collector marking of
gt_ggc_mx_lang_tree_node -- while it compiles
src/python_interface/py_predefined.cpp, the heaviest binding TU in the
build.  It reproduces on every Linux GCC builder, see olemke/arts
Actions run 38897484091.  The generator change is reverted here and a
comment left in its place so it does not come straight back.

Give Clang the headroom instead.  -fconstexpr-steps=4000000 is ~3.7x the
measured cost, enough for the species list to grow several times over
while still stopping a runaway constexpr loop quickly.  GCC's equivalent
-fconstexpr-ops-limit default (33.5M) and MSVC's /constexpr:steps default
(100M) already cover it, so only Clang needs the flag.

Verified with clang 23.1.3 on src/core/spec/isotopologues.cc: without the
flag it fails at auto_isotopologues.h:7 with the step-limit note, with it
the TU compiles clean.
Raise the clangxx upper bound from <23 to <24 so that conda
can solve environment-dev-mac.yml with the Clang 23.x series,
which is already in use on macOS workstations.
@riclarsson
riclarsson merged commit 831e24b into atmtools:main Oct 20, 2026
9 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