Observation
GCC 16.1 (xim gcc@16.1.0, the toolchain mcpp's manifest pins on Linux) segfaults while compiling src/main.cpp whenever mcpp.build.prepare gains a new interface unit in its import chain:
src/main.cpp:5:17: internal compiler error: Segmentation fault
5 | import mcpp.cli;
The backtrace reported during the first occurrence runs through module_state::read_namespaces → add_imported_namespace → get_originating_module_decl. Every module unit compiles; only the import in main.cpp fails. LLVM 22.1.8 builds the same trees.
Measurements
Each row is a full build of mcpp on x86_64 Linux.
| # |
Organisation |
GCC 16.1 |
LLVM 22.1.8 |
| E1 |
speak-agent/mcpp branch wip/prepare-split (469c3dd): five separately named modules mcpp.build.prepare.{context,manifest_merge,manifest_steps,provision,target_env}, two re-exported with export import |
ICE |
builds |
| E3 |
E1 with the five units turned into interface partitions mcpp.build.prepare:<x>, all export imported |
ICE |
not run |
| E4 |
2026.9.27.1 plus one near-empty interface module whose only content is a function returning a string, with the 13 imports of E1's context unit (mcpp.manifest, mcpp.toolchain.{model,fingerprint,triple,msvc,stdmod}, mcpp.xlings.runtime_selection, mcpp.runtime.binding, mcpp.wire, mcpp.build.plan, mcpp.modgraph.graph, mcpp.bmi_cache), imported by mcpp.build.prepare |
ICE |
not run |
| E5 |
2026.9.27.1 with two functions' definitions moved into an implementation unit module mcpp.build.prepare; |
builds |
not run |
| E6 |
E5 plus an implementation partition module mcpp.build.prepare:state; with E4's 13 imports, imported only by that implementation unit |
builds |
not run |
The trigger is structural: a new interface unit (a named module or an interface partition) between mcpp.build.prepare and its imports crashes the compiler whatever the unit contains (E4). Implementation units, and an implementation partition that only implementation units import, stay out of the interface's dependency chain and compile (E5, E6).
Earlier observations with the same signature:
- the cloud session that produced 2026.9.27.1 could not remove any of the 22 top-level declarations of
src/cli/cmd_build.cppm while keeping the crash, and found it needs an import chain of depth two (main imports A, A imports B, B imports mcpp.cli.cmd_build);
src/project.cppm carries a copy of package_key because importing mcpp.xlings.address_set there crashed the same way (see the comment near inherit_workspace_xlings).
Consequence for mcpp
src/build/prepare.cppm is decomposed in 2026.9.27.1 (#719) using only implementation units and an implementation partition imported by implementation units, per E5 and E6. A future change that adds an interface partition or a new named module to that chain will hit this crash on GCC 16.1.
Next steps
- Reduce outside mcpp to a standalone reproducer and report it to GCC bugzilla (needs an account).
- Re-test with a GCC 16 branch snapshot when xim carries one.
Observation
GCC 16.1 (xim
gcc@16.1.0, the toolchain mcpp's manifest pins on Linux) segfaults while compilingsrc/main.cppwhenevermcpp.build.preparegains a new interface unit in its import chain:The backtrace reported during the first occurrence runs through
module_state::read_namespaces→add_imported_namespace→get_originating_module_decl. Every module unit compiles; only the import inmain.cppfails. LLVM 22.1.8 builds the same trees.Measurements
Each row is a full build of mcpp on x86_64 Linux.
speak-agent/mcppbranchwip/prepare-split(469c3dd): five separately named modulesmcpp.build.prepare.{context,manifest_merge,manifest_steps,provision,target_env}, two re-exported withexport importmcpp.build.prepare:<x>, allexport importedcontextunit (mcpp.manifest,mcpp.toolchain.{model,fingerprint,triple,msvc,stdmod},mcpp.xlings.runtime_selection,mcpp.runtime.binding,mcpp.wire,mcpp.build.plan,mcpp.modgraph.graph,mcpp.bmi_cache), imported bymcpp.build.preparemodule mcpp.build.prepare;module mcpp.build.prepare:state;with E4's 13 imports, imported only by that implementation unitThe trigger is structural: a new interface unit (a named module or an interface partition) between
mcpp.build.prepareand its imports crashes the compiler whatever the unit contains (E4). Implementation units, and an implementation partition that only implementation units import, stay out of the interface's dependency chain and compile (E5, E6).Earlier observations with the same signature:
src/cli/cmd_build.cppmwhile keeping the crash, and found it needs an import chain of depth two (mainimports A, A imports B, B importsmcpp.cli.cmd_build);src/project.cppmcarries a copy ofpackage_keybecause importingmcpp.xlings.address_setthere crashed the same way (see the comment nearinherit_workspace_xlings).Consequence for mcpp
src/build/prepare.cppmis decomposed in 2026.9.27.1 (#719) using only implementation units and an implementation partition imported by implementation units, per E5 and E6. A future change that adds an interface partition or a new named module to that chain will hit this crash on GCC 16.1.Next steps