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 0beaca9548a524557d33d3c618e5ec586cf489d3
parent ed176e4211b27218b9182ead05a13fd6d27d46ac
Author: Michael Forney <mforney@mforney.org>
Date:   Sun, 17 Feb 2019 13:01:51 -0800

Allow computing address of non-lvalue structs/unions

We currently compile '.' member access as taking the address of
the struct, adding the offset, and then dereferencing as the member
type. However, the '.' operator is allowed on non-lvalues, even though
the '&' operator is not. So, we need to handle arbitrary struct/union
expressions in objectaddr by just compiling them normally, then converting
them to regular pointers (since struct/union values are just pointers
with additional type information).

Diffstat:
Mqbe.c | 9+++++++--
Mtests/struct-return-2.c | 6+++---
Mtests/struct-return-2.qbe | 14++++++++++----
3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/qbe.c b/qbe.c @@ -463,8 +463,13 @@ objectaddr(struct function *f, struct expression *e) funcinit(f, d, e->compound.init); return d->value; case EXPRUNARY: - if (e->unary.op == TMUL) - return funcexpr(f, e->unary.base); + if (e->unary.op != TMUL) + break; + return funcexpr(f, e->unary.base); + default: + if (e->type->kind != TYPESTRUCT && e->type->kind != TYPEUNION) + break; + return funcinst(f, ICOPY, &iptr, (struct value *[]){funcexpr(f, e)}); } error(&tok.loc, "expression is not an object"); } diff --git a/tests/struct-return-2.c b/tests/struct-return-2.c @@ -1,4 +1,4 @@ -struct s {int x;} g(void); -void f(void) { - g(); +struct {int x, y;} g(void); +int f(void) { + return g().y; } diff --git a/tests/struct-return-2.qbe b/tests/struct-return-2.qbe @@ -1,8 +1,14 @@ -type :s.1 = { w, } +type :.1 = { w, w, } export -function $f() { +function w $f() { @start.1 @body.2 - %.1 =:s.1 call $g() - ret + %.1 =:.1 call $g() + %.2 =l copy %.1 + %.3 =l copy %.2 + %.4 =l mul 4, 1 + %.5 =l add %.3, %.4 + %.6 =l copy %.5 + %.7 =w loadsw %.6 + ret %.7 }