aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-09-07 12:50:50 -0700
committerMichael Forney <mforney@mforney.org>2021-09-07 13:19:19 -0700
commit97c8fc5358bbecb6e2452425861e6cd5a5c93f91 (patch)
tree8bebb448e9c460072bf4e2aa52dce138d9ffcd1c
parent056c471bb7f85854e2af7a0166785d06820b251a (diff)
expr: Fix varargs again and add more tests
-rw-r--r--expr.c12
-rw-r--r--test/builtin-va-copy+x86_64.c9
-rw-r--r--test/builtin-va-copy+x86_64.qbe44
l---------[-rw-r--r--]test/varargs+aarch64.c13
-rw-r--r--test/varargs+aarch64.qbe39
l---------[-rw-r--r--]test/varargs+riscv64.c13
-rw-r--r--test/varargs+riscv64.qbe41
-rw-r--r--test/varargs+x86_64.c16
-rw-r--r--test/varargs+x86_64.qbe41
-rw-r--r--test/varargs-pass-valist+aarch64.c5
-rw-r--r--test/varargs-pass-valist+aarch64.qbe9
-rw-r--r--test/varargs-pass-valist+riscv64.c5
-rw-r--r--test/varargs-pass-valist+riscv64.qbe9
-rw-r--r--test/varargs-pass-valist+x86_64.c5
-rw-r--r--test/varargs-pass-valist+x86_64.qbe8
15 files changed, 174 insertions, 95 deletions
diff --git a/expr.c b/expr.c
index 323cbb7..d1458a4 100644
--- a/expr.c
+++ b/expr.c
@@ -645,7 +645,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
e->base = assignexpr(s);
if (!typesame(e->base->type, typeadjvalist))
error(&tok.loc, "va_arg argument must have type va_list");
- if (!e->base->decayed)
+ if (typeadjvalist == targ->typevalist)
e->base = mkunaryexpr(TBAND, e->base);
expect(TCOMMA, "after va_list");
e->type = typename(s, &e->qual);
@@ -655,14 +655,14 @@ builtinfunc(struct scope *s, enum builtinkind kind)
e->assign.l = assignexpr(s);
if (!typesame(e->assign.l->type, typeadjvalist))
error(&tok.loc, "va_copy destination must have type va_list");
- if (e->assign.l->decayed)
- e->assign.l = e->assign.l->base;
+ if (typeadjvalist != targ->typevalist)
+ e->assign.l = mkunaryexpr(TMUL, e->assign.l);
expect(TCOMMA, "after target va_list");
e->assign.r = assignexpr(s);
if (!typesame(e->assign.r->type, typeadjvalist))
error(&tok.loc, "va_copy source must have type va_list");
- if (e->assign.r->decayed)
- e->assign.r = e->assign.r->base;
+ if (typeadjvalist != targ->typevalist)
+ e->assign.r = mkunaryexpr(TMUL, e->assign.r);
break;
case BUILTINVAEND:
e = assignexpr(s);
@@ -677,7 +677,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
e->base = assignexpr(s);
if (!typesame(e->base->type, typeadjvalist))
error(&tok.loc, "va_start argument must have type va_list");
- if (!e->base->decayed)
+ if (typeadjvalist == targ->typevalist)
e->base = mkunaryexpr(TBAND, e->base);
expect(TCOMMA, "after va_list");
param = assignexpr(s);
diff --git a/test/builtin-va-copy+x86_64.c b/test/builtin-va-copy+x86_64.c
index 7a69596..48577ed 100644
--- a/test/builtin-va-copy+x86_64.c
+++ b/test/builtin-va-copy+x86_64.c
@@ -1,4 +1,11 @@
-void f(void) {
+void f1(void) {
static __builtin_va_list a, b;
__builtin_va_copy(a, b);
}
+void f2(__builtin_va_list b) {
+ static __builtin_va_list a;
+ __builtin_va_copy(a, b);
+}
+void f3(__builtin_va_list a, __builtin_va_list b) {
+ __builtin_va_copy(a, b);
+}
diff --git a/test/builtin-va-copy+x86_64.qbe b/test/builtin-va-copy+x86_64.qbe
index 47e1d9e..de2fa5a 100644
--- a/test/builtin-va-copy+x86_64.qbe
+++ b/test/builtin-va-copy+x86_64.qbe
@@ -1,7 +1,7 @@
data $.La.2 = align 8 { z 24 }
data $.Lb.3 = align 8 { z 24 }
export
-function $f() {
+function $f1() {
@start.1
@body.2
%.1 =l loadl $.Lb.3
@@ -16,3 +16,45 @@ function $f() {
storel %.7, %.6
ret
}
+data $.La.5 = align 8 { z 24 }
+export
+function $f2(l %.1) {
+@start.3
+ %.2 =l alloc8 8
+ storel %.1, %.2
+@body.4
+ %.3 =l loadl %.2
+ %.4 =l loadl %.3
+ storel %.4, $.La.5
+ %.5 =l add %.3, 8
+ %.6 =l add $.La.5, 8
+ %.7 =l loadl %.5
+ storel %.7, %.6
+ %.8 =l add %.5, 8
+ %.9 =l add %.6, 8
+ %.10 =l loadl %.8
+ storel %.10, %.9
+ ret
+}
+export
+function $f3(l %.1, l %.3) {
+@start.5
+ %.2 =l alloc8 8
+ storel %.1, %.2
+ %.4 =l alloc8 8
+ storel %.3, %.4
+@body.6
+ %.5 =l loadl %.4
+ %.6 =l loadl %.2
+ %.7 =l loadl %.5
+ storel %.7, %.6
+ %.8 =l add %.5, 8
+ %.9 =l add %.6, 8
+ %.10 =l loadl %.8
+ storel %.10, %.9
+ %.11 =l add %.8, 8
+ %.12 =l add %.9, 8
+ %.13 =l loadl %.11
+ storel %.13, %.12
+ ret
+}
diff --git a/test/varargs+aarch64.c b/test/varargs+aarch64.c
index 0b5a73d..c9c990c 100644..120000
--- a/test/varargs+aarch64.c
+++ b/test/varargs+aarch64.c
@@ -1,12 +1 @@
-void f(int n, ...) {
- __builtin_va_list ap;
-
- __builtin_va_start(ap, n);
- while (n) {
- __builtin_va_arg(ap, int);
- __builtin_va_arg(ap, float);
- __builtin_va_arg(ap, char *);
- --n;
- }
- __builtin_va_end(ap);
-}
+varargs+x86_64.c \ No newline at end of file
diff --git a/test/varargs+aarch64.qbe b/test/varargs+aarch64.qbe
index 512a8c7..5b6e830 100644
--- a/test/varargs+aarch64.qbe
+++ b/test/varargs+aarch64.qbe
@@ -1,22 +1,47 @@
+type :va_list.1 = align 8 { 32 }
export
-function $f(w %.1, ...) {
+function w $f1(w %.1, :va_list.1 %.3) {
@start.1
%.2 =l alloc4 4
storew %.1, %.2
- %.3 =l alloc8 32
@body.2
+ %.4 =w vaarg %.3
+ ret %.4
+}
+export
+function w $f2(w %.1, ...) {
+@start.3
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc4 4
+ %.4 =l alloc8 32
+@body.4
+ vastart %.4
+ %.5 =w loadw %.2
+ %.6 =w call $f1(w %.5, :va_list.1 %.4)
+ storew %.6, %.3
+ %.7 =w loadw %.3
+ ret %.7
+}
+export
+function $f3(w %.1, ...) {
+@start.5
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc8 32
+@body.6
vastart %.3
-@while_cond.3
+@while_cond.7
%.4 =w loadw %.2
- jnz %.4, @while_body.4, @while_join.5
-@while_body.4
+ jnz %.4, @while_body.8, @while_join.9
+@while_body.8
%.5 =w vaarg %.3
%.6 =s vaarg %.3
%.7 =l vaarg %.3
%.8 =w loadw %.2
%.9 =w sub %.8, 1
storew %.9, %.2
- jmp @while_cond.3
-@while_join.5
+ jmp @while_cond.7
+@while_join.9
ret
}
diff --git a/test/varargs+riscv64.c b/test/varargs+riscv64.c
index 0b5a73d..c9c990c 100644..120000
--- a/test/varargs+riscv64.c
+++ b/test/varargs+riscv64.c
@@ -1,12 +1 @@
-void f(int n, ...) {
- __builtin_va_list ap;
-
- __builtin_va_start(ap, n);
- while (n) {
- __builtin_va_arg(ap, int);
- __builtin_va_arg(ap, float);
- __builtin_va_arg(ap, char *);
- --n;
- }
- __builtin_va_end(ap);
-}
+varargs+x86_64.c \ No newline at end of file
diff --git a/test/varargs+riscv64.qbe b/test/varargs+riscv64.qbe
index 7fcda8d..a918014 100644
--- a/test/varargs+riscv64.qbe
+++ b/test/varargs+riscv64.qbe
@@ -1,22 +1,49 @@
export
-function $f(w %.1, ...) {
+function w $f1(w %.1, l %.3) {
@start.1
%.2 =l alloc4 4
storew %.1, %.2
- %.3 =l alloc8 8
+ %.4 =l alloc8 8
+ storel %.3, %.4
@body.2
+ %.5 =w vaarg %.4
+ ret %.5
+}
+export
+function w $f2(w %.1, ...) {
+@start.3
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc4 4
+ %.4 =l alloc8 8
+@body.4
+ vastart %.4
+ %.5 =w loadw %.2
+ %.6 =l loadl %.4
+ %.7 =w call $f1(w %.5, l %.6)
+ storew %.7, %.3
+ %.8 =w loadw %.3
+ ret %.8
+}
+export
+function $f3(w %.1, ...) {
+@start.5
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc8 8
+@body.6
vastart %.3
-@while_cond.3
+@while_cond.7
%.4 =w loadw %.2
- jnz %.4, @while_body.4, @while_join.5
-@while_body.4
+ jnz %.4, @while_body.8, @while_join.9
+@while_body.8
%.5 =w vaarg %.3
%.6 =s vaarg %.3
%.7 =l vaarg %.3
%.8 =w loadw %.2
%.9 =w sub %.8, 1
storew %.9, %.2
- jmp @while_cond.3
-@while_join.5
+ jmp @while_cond.7
+@while_join.9
ret
}
diff --git a/test/varargs+x86_64.c b/test/varargs+x86_64.c
index 0b5a73d..71bf1d3 100644
--- a/test/varargs+x86_64.c
+++ b/test/varargs+x86_64.c
@@ -1,4 +1,18 @@
-void f(int n, ...) {
+int f1(int n, __builtin_va_list ap) {
+ return __builtin_va_arg(ap, int);
+}
+
+int f2(int n, ...) {
+ int r;
+ __builtin_va_list ap;
+
+ __builtin_va_start(ap, n);
+ r = f1(n, ap);
+ __builtin_va_end(ap);
+ return r;
+}
+
+void f3(int n, ...) {
__builtin_va_list ap;
__builtin_va_start(ap, n);
diff --git a/test/varargs+x86_64.qbe b/test/varargs+x86_64.qbe
index 641afa1..46904b6 100644
--- a/test/varargs+x86_64.qbe
+++ b/test/varargs+x86_64.qbe
@@ -1,22 +1,49 @@
export
-function $f(w %.1, ...) {
+function w $f1(w %.1, l %.3) {
@start.1
%.2 =l alloc4 4
storew %.1, %.2
- %.3 =l alloc8 24
+ %.4 =l alloc8 8
+ storel %.3, %.4
@body.2
+ %.5 =l loadl %.4
+ %.6 =w vaarg %.5
+ ret %.6
+}
+export
+function w $f2(w %.1, ...) {
+@start.3
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc4 4
+ %.4 =l alloc8 24
+@body.4
+ vastart %.4
+ %.5 =w loadw %.2
+ %.6 =w call $f1(w %.5, l %.4)
+ storew %.6, %.3
+ %.7 =w loadw %.3
+ ret %.7
+}
+export
+function $f3(w %.1, ...) {
+@start.5
+ %.2 =l alloc4 4
+ storew %.1, %.2
+ %.3 =l alloc8 24
+@body.6
vastart %.3
-@while_cond.3
+@while_cond.7
%.4 =w loadw %.2
- jnz %.4, @while_body.4, @while_join.5
-@while_body.4
+ jnz %.4, @while_body.8, @while_join.9
+@while_body.8
%.5 =w vaarg %.3
%.6 =s vaarg %.3
%.7 =l vaarg %.3
%.8 =w loadw %.2
%.9 =w sub %.8, 1
storew %.9, %.2
- jmp @while_cond.3
-@while_join.5
+ jmp @while_cond.7
+@while_join.9
ret
}
diff --git a/test/varargs-pass-valist+aarch64.c b/test/varargs-pass-valist+aarch64.c
deleted file mode 100644
index c1ede84..0000000
--- a/test/varargs-pass-valist+aarch64.c
+++ /dev/null
@@ -1,5 +0,0 @@
-void f(__builtin_va_list ap);
-void g(void) {
- static __builtin_va_list ap;
- f(ap);
-}
diff --git a/test/varargs-pass-valist+aarch64.qbe b/test/varargs-pass-valist+aarch64.qbe
deleted file mode 100644
index 67cef8a..0000000
--- a/test/varargs-pass-valist+aarch64.qbe
+++ /dev/null
@@ -1,9 +0,0 @@
-data $.Lap.2 = align 8 { z 32 }
-type :va_list.1 = align 8 { 32 }
-export
-function $g() {
-@start.1
-@body.2
- call $f(:va_list.1 $.Lap.2)
- ret
-}
diff --git a/test/varargs-pass-valist+riscv64.c b/test/varargs-pass-valist+riscv64.c
deleted file mode 100644
index c1ede84..0000000
--- a/test/varargs-pass-valist+riscv64.c
+++ /dev/null
@@ -1,5 +0,0 @@
-void f(__builtin_va_list ap);
-void g(void) {
- static __builtin_va_list ap;
- f(ap);
-}
diff --git a/test/varargs-pass-valist+riscv64.qbe b/test/varargs-pass-valist+riscv64.qbe
deleted file mode 100644
index 937f50a..0000000
--- a/test/varargs-pass-valist+riscv64.qbe
+++ /dev/null
@@ -1,9 +0,0 @@
-data $.Lap.2 = align 8 { z 8 }
-export
-function $g() {
-@start.1
-@body.2
- %.1 =l loadl $.Lap.2
- call $f(l %.1)
- ret
-}
diff --git a/test/varargs-pass-valist+x86_64.c b/test/varargs-pass-valist+x86_64.c
deleted file mode 100644
index c1ede84..0000000
--- a/test/varargs-pass-valist+x86_64.c
+++ /dev/null
@@ -1,5 +0,0 @@
-void f(__builtin_va_list ap);
-void g(void) {
- static __builtin_va_list ap;
- f(ap);
-}
diff --git a/test/varargs-pass-valist+x86_64.qbe b/test/varargs-pass-valist+x86_64.qbe
deleted file mode 100644
index 50d9283..0000000
--- a/test/varargs-pass-valist+x86_64.qbe
+++ /dev/null
@@ -1,8 +0,0 @@
-data $.Lap.2 = align 8 { z 24 }
-export
-function $g() {
-@start.1
-@body.2
- call $f(l $.Lap.2)
- ret
-}