diff options
| author | 2023-06-04 11:20:43 +0200 | |
|---|---|---|
| committer | 2023-06-04 11:20:43 +0200 | |
| commit | b295cd602d59888c373819ec3bcd63e12f008702 (patch) | |
| tree | 8e3a6b6c0262451b040659e67164bb85635a2512 | |
| parent | 51197251c464a742c5bef5a67c6da222d32b14d3 (diff) | |
bugfix
| -rw-r--r-- | abi0.c | 29 | ||||
| -rw-r--r-- | irdump.c | 4 | ||||
| -rw-r--r-- | parse.c | 7 | ||||
| -rw-r--r-- | test.c | 7 |
4 files changed, 31 insertions, 16 deletions
@@ -291,29 +291,28 @@ abi0(struct function *fn) int thisi = sretarghidden + ni + nf + ns; int first = abiargs.n; int ret = abiarg(&abiargs, &ni, &nf, &ns, pty); + union ref argss[2]; + union irtype typss[2]; + ret = patcharg(argss, typss, blk, &iinstr, call, i, ret, &abiargs.p[first]); if (structbyval) { - union ref argss[2]; - union irtype typss[2]; - assert(structbyval); - ret = patcharg(argss, typss, blk, &iinstr, call, i, ret, &abiargs.p[first]); vpushn(&newargs, argss, ret); vpushn(&newtyps, typss, ret); - if (call->vararg == i) - vararg = thisi; } + if (call->vararg == i) + vararg = thisi; } call->sret = 0; call->vararg = vararg; - if (structbyval) { - if (newargs.n != call->narg) { - call->args = alloc(&fn->arena, newargs.n * (sizeof *newargs.p + sizeof *newtyps.p), 0); - call->typs = (union irtype *)((char *)call->args + newargs.n * sizeof *newargs.p); - } - memcpy(call->args, newargs.p, newargs.n * sizeof *call->args); - memcpy(call->typs, newtyps.p, newtyps.n * sizeof *call->typs); - call->abiargregs = alloc(&fn->arena, abiargs.n * sizeof *call->abiargregs, 0); - for (int i = 0; i < abiargs.n; ++i) call->abiargregs[i] = abiargs.p[i].reg; + if (structbyval && newargs.n != call->narg) { + call->args = alloc(&fn->arena, newargs.n * (sizeof *newargs.p + sizeof *newtyps.p), 0); + call->typs = (union irtype *)((char *)call->args + newargs.n * sizeof *newargs.p); } + memcpy(call->typs, newtyps.p, newtyps.n * sizeof *call->typs); + if (structbyval) + memcpy(call->args, newargs.p, newargs.n * sizeof *call->args); + call->abiargregs = alloc(&fn->arena, abiargs.n * sizeof *call->abiargregs, 0); + for (int i = 0; i < abiargs.n; ++i) call->abiargregs[i] = abiargs.p[i].reg; + call->narg = abiargs.n; vfree(&abiargs); vfree(&newargs); vfree(&newtyps); @@ -63,6 +63,10 @@ dumpref(enum op o, union ref ref) if (i > 0 || call->sret) efmt(", "); if (call->vararg == i) efmt("..., "); + if (call->abiargregs) { + short r = call->abiargregs[i]; + efmt("(%ls) ", r != -1 ? mctarg->rnames[r] : "<stk>"); + } prityp(call->typs[i]); efmt(" "); dumpref(0, call->args[i]); @@ -1763,7 +1763,12 @@ block(struct parser *pr, struct function *fn) error(&span, "cannot initialize '%ty' variable with '%ty'", decl.ty, ini.ty); } - EMITS genstore(fn, decl.ty, mkref(RTMP, decl.id), exprvalue(fn, &ini)); + EMITS { + if (isagg(decl.ty)) + structcopy(fn, mkref(RTMP, decl.id), &ini); + else + genstore(fn, decl.ty, mkref(RTMP, decl.id), exprvalue(fn, &ini)); + } } break; case SCTYPEDEF: break; @@ -51,6 +51,13 @@ void silly(struct pair *p, struct quad *q) *q = quad(1,2,3,4); } +void test2(struct big *b) { + struct big s = *b; + extern void h(int, struct big, float); + s.x[5] += 2; + h(0, s, 0); +} + struct f2 { float f,g; }; struct f2 f2test(struct f2 *r) { return *r; |