https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120870
--- Comment #24 from Sam James <sjames at gcc dot gnu.org> ---
Looking at this a bit again with Python 3.14.4 and `./configure
--with-tail-call-interp --disable-gil CFLAGS="-O2 -march=znver2 -ggdb3"` with
trunk.
It crashes like this with some noipa added to make debugging easier:
```
Program received signal SIGSEGV, Segmentation fault.
0x000055ff45031552 in PyType_HasFeature (type=type@entry=0xd85d8b4800000115,
feature=feature@entry=2048) at ./Include/object.h:795
795 return ((flags & feature) != 0);
(gdb) bt
#0 0x000055ff45031552 in PyType_HasFeature
(type=type@entry=0xd85d8b4800000115, feature=feature@entry=2048) at
./Include/object.h:795
#1 0x000055ff4503157a in _PyVectorcall_FunctionInline
(callable=callable@entry=0x55ff451b4734 <_PyEval_EvalFrameDefault+436>) at
./Include/internal/pycore_call.h:129
#2 0x000055ff45031ccf in _PyObject_VectorcallTstate (tstate=0x55ff455cc170
<_PyRuntime+346736>, callable=callable@entry=0x55ff451b4734
<_PyEval_EvalFrameDefault+436>, args=args@entry=0x7ffc5e7e40a8,
nargsf=9223372036854775812, kwnames=kwnames@entry=0x0) at
./Include/internal/pycore_call.h:172
#3 0x000055ff45032269 in PyObject_Vectorcall
(callable=callable@entry=0x55ff451b4734 <_PyEval_EvalFrameDefault+436>,
args=args@entry=0x7ffc5e7e40a8, nargsf=<optimized out>,
kwnames=kwnames@entry=0x0)
at Objects/call.c:328
#4 0x000055ff451b8e37 in _TAIL_CALL_CALL (frame=0x7f7819972020,
stack_pointer=<optimized out>, tstate=<optimized out>,
next_instr=0x32512441324, oparg=3) at Python/generated_cases.c.h:1621
Backtrace stopped: Cannot access memory at address 0xfffffffffffffffb
```
callable->ob_type is a garbage pointer when it is retrieved:
```
(gdb) p type
$13 = (PyTypeObject *) 0xd85d8b4800000115
(gdb) p *type
❌ Cannot access memory at address 0xd85d8b4800000115
```
If we go back to frame 4 before it calls PyObject_Vectorcall, it looks OK? In
Python/generated_cases.c.h:1621, there's:
(gdb) list .
1616 JUMP_TO_LABEL(error);
1617 }
1618 stack_pointer[-2 - oparg] = callable;
1619 stack_pointer[-1 - oparg] = self_or_null;
1620 _PyFrame_SetStackPointer(frame, stack_pointer);
1621 PyObject *res_o = PyObject_Vectorcall(
1622 callable_o, args_o,
1623 total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
1624 NULL);
1625 stack_pointer = _PyFrame_GetStackPointer(frame);
0x000055ff451b8e06 <+406>: inc rax
0x000055ff451b8e09 <+409>: cmp r11,rsi
0x000055ff451b8e0c <+412>: jg 0x55ff451b8df6 <_TAIL_CALL_CALL+390>
0x000055ff451b8e0e <+414>: mov rax,QWORD PTR [rbp-0x80]
=> 0x000055ff451b8e12 <+418>: mov rdi,QWORD PTR [rbp-0x98]
(gdb) p *(PyTypeObject*)($rbp-0x80)
...
which looks like a reasonable(?) PyTypeObject, so it gets corrupted later.
Unfortunately Python/generated_cases.c.h is a large generated file (even
without expanding macros).