diff options
author | Michael Forney <mforney@mforney.org> | 2021-10-18 10:49:24 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-10-18 10:49:24 -0700 |
commit | f3391dde28a8ab2a6652cd43c7f58cafa04a5861 (patch) | |
tree | c1bae2ac7422e1efdccc371d21e313942d041cd5 | |
parent | badc674ce4e77cd29645cd1cd9df5e57f47e08ae (diff) |
expr: Make sure __builtin_va_end argument is evaluated for side-effects
-rw-r--r-- | expr.c | 3 | ||||
-rw-r--r-- | qbe.c | 3 | ||||
-rw-r--r-- | test/varargs+riscv64.qbe | 6 |
3 files changed, 5 insertions, 7 deletions
@@ -668,8 +668,7 @@ builtinfunc(struct scope *s, enum builtinkind kind) e = assignexpr(s); if (!typesame(e->type, typeadjvalist)) error(&tok.loc, "va_end argument must have type va_list"); - e = mkexpr(EXPRBUILTIN, &typevoid, NULL); - e->builtin.kind = BUILTINVAEND; + e = exprconvert(e, &typevoid); break; case BUILTINVASTART: e = mkexpr(EXPRBUILTIN, &typevoid, assignexpr(s)); @@ -937,9 +937,6 @@ funcexpr(struct func *f, struct expr *e) error(&tok.loc, "va_arg with non-scalar type is not yet supported"); l = funcexpr(f, e->base); return funcinst(f, IVAARG, qbetype(e->type).base, l, NULL); - case BUILTINVAEND: - /* no-op */ - break; case BUILTINALLOCA: l = funcexpr(f, e->base); return funcinst(f, IALLOC16, ptrclass, l, NULL); diff --git a/test/varargs+riscv64.qbe b/test/varargs+riscv64.qbe index a918014..48638bb 100644 --- a/test/varargs+riscv64.qbe +++ b/test/varargs+riscv64.qbe @@ -22,8 +22,9 @@ function w $f2(w %.1, ...) { %.6 =l loadl %.4 %.7 =w call $f1(w %.5, l %.6) storew %.7, %.3 - %.8 =w loadw %.3 - ret %.8 + %.8 =l loadl %.4 + %.9 =w loadw %.3 + ret %.9 } export function $f3(w %.1, ...) { @@ -45,5 +46,6 @@ function $f3(w %.1, ...) { storew %.9, %.2 jmp @while_cond.7 @while_join.9 + %.10 =l loadl %.3 ret } |