riscv64-gen: Fix `load` and `store` type_size usage
commitc7263571d217e0863d3e62629207659b6aaf2b8b
authorEkaitz Zarraga <ekaitz@elenq.tech>
Sat, 20 Jan 2024 22:36:45 +0000 (20 23:36 +0100)
committerEkaitz Zarraga <ekaitz@elenq.tech>
Mon, 29 Jan 2024 10:09:59 +0000 (29 11:09 +0100)
tree10d712de5a7e81e1a6e23141449020e0c855e27a
parent7f0a28f6ca026a0b2b50282a2168346eef668651
riscv64-gen: Fix `load` and `store` type_size usage

In `load` and `store` RISC-V gen used `type_size` to retrieve the size
of the types being moved around, the problem with that function is it
tries to obtain internal information of the type. When using `type_size`
with a `char *` it returns 1, and emits a `lb` instruction when using a
conditional expression like so (but probably also in other cases):

    char *a, *b;
    b = "hello";
    a = x ? b : "" ;                // this emits an `lb`

That `lb` clobbers the pointer, only loading the latest byte of it:

    // if `b` was, say: 0x1f822e
    a = b;
    // now `a` is 0x00002e

NOTE: We spotted this when building make-3.82, in `init_switches`
      function in the `main.c` file. This error made `make` unable to
      run long options like `make --help` (segfault when doing the
      `strlen` later)

This happens because a `char *` is internally stored as a `char[1]` or
something similar, it's result is the size of a `char` (1) times the
size of the array `1`. This is not what we want, we are copying the
pointer, not the array itself. Using `type_size` for this is not
appropriate even if it works for some cases.

If the conditional expression is rewritten to imperative style using an
`if` it works properly, so it might be related with the fact the pointer
is `load`ed to a register.

`load` and `store` should only work with integral types, so reading the
size of the array is not useful. This commit creates a simpler version
of this function that only reads the integral type of what's working
with: char * is considered just a pointer. So it makes an `ld` instead,
and the code above works.
riscv64-gen.c