https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125768
Bug ID: 125768
Summary: `[16 Regression] c++/modules: ICE (segfault
build_special_member_call) on member-init of a
module-attached class with dense members when 'import
std'`
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: emmanuel.prunet at hotmail dot fr
Target Milestone: ---
## Description
`g++ -fmodules -std=gnu++23` segfaults (ICE) while synthesising the member-init
list of a module-attached class's constructor, defined in a module
implementation unit, when the class has a dense set of members AND `std` is
reached through `import std;` The crash is in `build_special_member_call`
(`cp/call.cc`), reached via `emit_mem_initializers` → `perform_member_init` →
`build_aggr_init` → `expand_default_init`.
Regression: gcc-15.2.0 compiles the identical translation units without error.
gcc-16.1.0 (GNU release tarball) ICEs; the ubuntu-toolchain-r/test 16.0.1 trunk
snapshot ICEs identically — so it is a released-version regression, not a
snapshot artifact. clang-21 + libc++ compiles the same construct cleanly.
`import std` is necessary: reaching the same std types via textual `#include`
in the global module fragment (instead of `import std;`) compiles cleanly —
only the module-std path ICEs. No single member triggers it; the crash needs
the combination (`std::atomic` ×3 + `std::function` +
`std::vector<imported-module type>` + `std::mt19937_64` + a cross-module
move-init + a global-module-fragment PIMPL fwd).
## Reproducer (self-contained, raw g++ — no build system)
Five files (below), then:
```sh
g++ -std=gnu++23 -fmodules -fmodule-only -c <libstdc++>/bits/std.cc # build
the std module (gcm.cache/std.gcm)
g++ -std=gnu++23 -fmodules -c api.cppm -o api.o # ok
g++ -std=gnu++23 -fmodules -c outer.cppm -o outer.o # ok
g++ -std=gnu++23 -fmodules -c outer_impl.cpp -o outer_impl.o # ICE:
segfault in build_special_member_call
```
(`<libstdc++>/bits/std.cc` is the libstdc++ std-module source, e.g.
`.../include/c++/16.1.0/bits/std.cc`. Equivalently reproducible via a CMake
target with
`CXX_MODULE_STD ON` over the same five files.)
### api.cppm
```cpp
module;
export module api;
import std;
namespace n {
export struct Config { std::string name; std::vector<int> weights; int v{0}; };
}
```
### impl_fwd.hpp
```cpp
#pragma once
namespace n { struct Impl; } // global-module-attached (textual) forward decl
```
### impl_def.hpp
```cpp
#pragma once
namespace n { struct Impl { int x{0}; }; }
```
### outer.cppm
```cpp
module;
#include "impl_fwd.hpp"
export module outer;
import std;
import api;
namespace n {
export struct Outer {
Config cfg;
std::unique_ptr<Impl> p;
std::atomic<double> a{0};
std::atomic<double> b{0};
std::atomic<bool> c{false};
std::function<void()> cb;
std::vector<Config> sub;
std::mt19937_64 rng;
explicit Outer(Config c, std::uint64_t seed);
~Outer();
};
}
```
### outer_impl.cpp (← ICE site)
```cpp
module;
#include "impl_def.hpp"
module outer;
import std;
import api;
namespace n {
Outer::Outer(Config c, std::uint64_t seed) : cfg{std::move(c)}, rng{seed} {}
Outer::~Outer() = default;
}
```
## ICE output / backtrace (gcc-16.1.0)
```
outer_impl.cpp: In constructor 'n::Outer@outer::Outer(n::Config@api,
uint64_t)':
outer_impl.cpp:7:65: internal compiler error: Segmentation fault
7 | Outer::Outer(Config c, std::uint64_t seed) : cfg{std::move(c)},
rng{seed} {}
|
^~~~~~~~~
0x234531b internal_error(char const*, ...)
gcc/diagnostic-global-context.cc:787
0x10eb213 crash_signal gcc/toplev.cc:325
0x8115a8 build_special_member_call(...) gcc/cp/call.cc:11688
0x8e53e4 expand_default_init gcc/cp/init.cc:2249
0x8e53e4 expand_aggr_init_1 gcc/cp/init.cc:2368
0x8e81d6 build_aggr_init(...) gcc/cp/init.cc:2087
0x8ec857 perform_member_init gcc/cp/init.cc:1169
0x8ec857 emit_mem_initializers(tree_node*) gcc/cp/init.cc:1643
0x9cc06a cp_parser_mem_initializer_list gcc/cp/parser.cc:19870
...
```
## Environment
- gcc-16.1.0 (GNU release tarball, `--enable-languages=c,c++ --disable-multilib
--disable-bootstrap`, x86_64-pc-linux-gnu). Also reproduced on the apt
`g++-16` 16.0.1 trunk snapshot (r16-8100).
- **Clean on:** gcc-15.2.0 (same files, same flags), and clang-21 + libc++.
- Flags: `-std=gnu++23 -fmodules` (CMake emits `-fmodules-ts -fmodule-mapper=…
-fdeps-format=p1689r5`).
## Why it matters (reporter context)
Surfaced converting a real engine library to C++23 modules: the engine's
module-attached `Agent`/`Engine` classes have exactly this member density, so
it is not dodgeable by restructuring. It blocks the libstdc++ `import std` leg
of a cross-stdlib build; the libc++/clang leg is unaffected.