diff options
author | Michael Forney <mforney@mforney.org> | 2021-04-11 01:49:15 -0700 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2021-07-29 23:37:57 +0200 |
commit | 98cd2e817616fff14622b8e514fc88b378a100ef (patch) | |
tree | 9d58b2183ad879f8b12cb07ccd1bea51d5082eae /load.c | |
parent | b543ffed71497fb079bfdca53934870a1189c325 (diff) | |
download | roux-98cd2e817616fff14622b8e514fc88b378a100ef.tar.gz |
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
diff --git a/load.c b/load.c index ae9cfcf..f3a695b 100644 --- a/load.c +++ b/load.c @@ -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); } } |