https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126454

Luke Wren <wren6991 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wren6991 at gmail dot com

--- Comment #3 from Luke Wren <wren6991 at gmail dot com> ---
I also hit this on 16.1.0 while debugging a regression in MicroPython from
15.2.0 to 16.1.0.

Reduced from the MicroPython source, compile with: riscv32-unknown-elf-gcc -c
repro.c -march=rv32i_zca_zcmp -Os

extern int mp_obj_get_type(int o);
extern int type_get_iternext(int type);
extern void mp_load_method_maybe(int o, int qstr, int *dest);
extern int mp_call_method_n_kw(int n_args, int n_kw, const int *args);
extern const char *mp_obj_get_type_str(int o);
extern void mp_raise_msg_varg(int type, const char *fmt, const char *arg)
    __attribute__((noreturn));

int mp_iternext_allow_raise(int o_in) {
    int dest[2];
    int type = mp_obj_get_type(o_in);
    if (type & 0x180) {
        int (*it)(int) = (void *)(long)type_get_iternext;
        return it(o_in);
    }
    mp_load_method_maybe(o_in, 25, dest);
    if (dest[0]) {
        return mp_call_method_n_kw(0, 0, dest);
    }
    const char *s = mp_obj_get_type_str(o_in);
    mp_raise_msg_varg(0, "'%s' object isn't an iterator", s);
}

Disassembly of the call to mp_call_method_n_kw:

0000004e <.L6>:
  4e:   0030                    addi    a2,sp,8
  50:   4581                    li      a1,0
  52:   00000097                auipc   ra,0x0
                        52: R_RISCV_CALL_PLT    mp_call_method_n_kw
                        52: R_RISCV_RELAX       *ABS*
  56:   000080e7                jalr    ra # 52 <.L6+0x4>
  5a:   bc56                    cm.popretz      {ra,s0},32


There are two distinct bugs caused by the absorption of the `li a0, 0` into
`cm.popretz`:

* First arg of mp_call_method_n_kw() is not initialised to 0, gets garbage
instead
* Return value from mp_iternext_allow_raise() is replaced with 0 instead of the
result of mp_call_method_n_kw()

Reply via email to