cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit ed176e4211b27218b9182ead05a13fd6d27d46ac
parent fed14a31ca554b54c4f2eebefd09aeaeda782aba
Author: Michael Forney <mforney@mforney.org>
Date:   Sun, 17 Feb 2019 13:39:02 -0800

Fix returning struct/union types

Diffstat:
Mqbe.c | 4+++-
Atests/struct-return-1.c | 3+++
Atests/struct-return-1.qbe | 10++++++++++
Atests/struct-return-2.c | 4++++
Atests/struct-return-2.qbe | 8++++++++
5 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/qbe.c b/qbe.c @@ -356,6 +356,7 @@ mkfunc(char *name, struct type *t, struct scope *s) f->start = f->end = (struct block *)mkblock("start"); f->gotos = mkhtab(8); f->lastid = 0; + emittype(t->base); /* allocate space for parameters */ for (p = t->func.params; p; p = p->next) { @@ -593,6 +594,7 @@ funcexpr(struct function *f, struct expression *e) case EXPRCALL: argvals = xreallocarray(NULL, e->call.nargs + 3, sizeof(argvals[0])); argvals[0] = funcexpr(f, e->call.func); + emittype(e->type); for (argval = &argvals[1], arg = e->call.args; arg; ++argval, arg = arg->next) { emittype(arg->type); *argval = funcexpr(f, arg); @@ -991,7 +993,7 @@ emittype(struct type *t) { static uint64_t id; - if (t->repr->abi.id || !(typeprop(t) & PROPAGGR)) + if (!t->repr || t->repr->abi.id || !(typeprop(t) & PROPAGGR)) return; t->repr = xmalloc(sizeof(*t->repr)); t->repr->base = 'l'; diff --git a/tests/struct-return-1.c b/tests/struct-return-1.c @@ -0,0 +1,3 @@ +struct s {int x;} f(void) { + return (struct s){2}; +} diff --git a/tests/struct-return-1.qbe b/tests/struct-return-1.qbe @@ -0,0 +1,10 @@ +type :s.1 = { w, } +export +function :s.1 $f() { +@start.1 + %.1 =l alloc4 4 +@body.2 + %.2 =l add %.1, 0 + storew 2, %.2 + ret %.1 +} diff --git a/tests/struct-return-2.c b/tests/struct-return-2.c @@ -0,0 +1,4 @@ +struct s {int x;} g(void); +void f(void) { + g(); +} diff --git a/tests/struct-return-2.qbe b/tests/struct-return-2.qbe @@ -0,0 +1,8 @@ +type :s.1 = { w, } +export +function $f() { +@start.1 +@body.2 + %.1 =:s.1 call $g() + ret +}