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.

Reply via email to