diff options
| author | Michael Forney <[email protected]> | 2021-04-11 01:49:15 -0700 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2021-07-29 23:37:57 +0200 |
| commit | 98cd2e817616fff14622b8e514fc88b378a100ef (patch) | |
| tree | 9d58b2183ad879f8b12cb07ccd1bea51d5082eae /load.c | |
| parent | b543ffed71497fb079bfdca53934870a1189c325 (diff) | |
load: handle all cases in cast()
Previously, all casts but d->w, d->s, l->s, s->d, w->d were supported.
At least the first three can occur by storing to then loading from
a slot, currently triggering an assertion failure. Though the other
two might not be possible, they are easy enough to support as well.
Fixes hare#360.
Diffstat (limited to 'load.c')
| -rw-r--r-- | load.c | 13 |
1 files changed, 8 insertions, 5 deletions
@@ -92,14 +92,17 @@ cast(Ref *r, int cls, Loc *l) cls0 = curf->tmp[r->val].cls; if (cls0 == cls || (cls == Kw && cls0 == Kl)) return; - assert(!KWIDE(cls0) || KWIDE(cls)); - if (KWIDE(cls) == KWIDE(cls0)) - *r = iins(cls, Ocast, *r, R, l); - else { - assert(cls == Kl); + if (KWIDE(cls0) < KWIDE(cls)) { if (cls0 == Ks) *r = iins(Kw, Ocast, *r, R, l); *r = iins(Kl, Oextuw, *r, R, l); + if (cls == Kd) + *r = iins(Kd, Ocast, *r, R, l); + } else { + if (cls0 == Kd && cls != Kl) + *r = iins(Kl, Ocast, *r, R, l); + if (cls0 != Kd || cls != Kw) + *r = iins(cls, Ocast, *r, R, l); } } |
