aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qbe.c9
-rw-r--r--tests/struct-return-2.c6
-rw-r--r--tests/struct-return-2.qbe14
3 files changed, 20 insertions, 9 deletions
diff --git a/qbe.c b/qbe.c
index 2080e7c..29f005b 100644
--- 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
index 9fa50f5..726e667 100644
--- 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
index 2f1d3da..415ec2f 100644
--- 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
}