https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124247
--- Comment #2 from Denys Kachalenko <kachalenko.denis at gmail dot com> ---
Further investigation shows this is not modules-specific. Minimal single-TU
reproducer (no modules):
// reproducer.cpp
#include <format>
#include <iostream>
struct Point { int X, Y; };
template<> struct std::formatter<Point> {
constexpr auto parse(std::format_parse_context& c) { return c.begin(); }
auto format(const Point& p, std::format_context& c) const {
return std::format_to(c.out(), "({}, {})", p.X, p.Y);
}
};
int main() { std::cout << std::format("{}", Point{10,20}) << std::endl; }
Build/run (GCC 16.0.1 20260221, x86_64-w64-mingw32):
$ g++ -std=c++26 -O0 -march=native -o test.exe reproducer.cpp
$ ./test.exe
Segmentation fault
$ g++ -std=c++26 -O0 -o test.exe reproducer.cpp
$ ./test.exe
(10, 20)
Crashes at all optimization levels (-O0 through -O3, -Og) with -march=native
(Alder Lake).
-march=x86-64: OK
-march=x86-64-v2: OK
-march=x86-64-v3: CRASH
-march=native: CRASH
The crash starts when AVX is enabled (>= x86-64-v3). From GDB, the crash is at
_Formatting_scanner::_M_format_arg (format:5166):
vmovdqu -0x30(%rbp),%ymm0 # load basic_format_arg (OK, unaligned)
vmovdqa %ymm0,-0x50(%rbp) # store to stack — SIGSEGV
sizeof(basic_format_arg<format_context>) = 32, alignof = 16. The compiler emits
vmovdqa (requires 32-byte alignment) for a type with 16-byte alignment. The
destination address is 16-byte aligned but not 32-byte aligned.
With builtin types (std::format("{}", 42)) the crash does not consistently
reproduce because the call stack depth happens to produce 32-byte aligned
addresses, but it can be triggered by shifting stack alignment.
My original report incorrectly attributed this to C++ modules — the build
system passes -march=native globally, which is the actual trigger. This appears
to be a manifestation of Bug 54412.