diff options
author | Michael Forney <mforney@mforney.org> | 2021-09-04 13:43:16 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-09-04 13:43:16 -0700 |
commit | 16c718729adfaf40cf22aa4efeafb0d92ef5ee3c (patch) | |
tree | 0155f5209d10487277fee876915eaa954742e66f /expr.c | |
parent | a1b0a66e186af524a76747fc990df07b6d325f38 (diff) |
Prepare for supporting architecture-specific va_list type
Diffstat (limited to 'expr.c')
-rw-r--r-- | expr.c | 29 |
1 files changed, 22 insertions, 7 deletions
@@ -642,26 +642,41 @@ builtinfunc(struct scope *s, enum builtinkind kind) case BUILTINVAARG: e = mkexpr(EXPRBUILTIN, NULL); e->builtin.kind = BUILTINVAARG; - e->base = exprconvert(assignexpr(s), &typevalistptr); + e->base = mkunaryexpr(TBAND, assignexpr(s)); + if (e->base->base->type != &typevalist) + error(&tok.loc, "va_arg argument must have type va_list"); expect(TCOMMA, "after va_list"); e->type = typename(s, &e->qual); break; case BUILTINVACOPY: - e = mkexpr(EXPRASSIGN, typevalist.base); - e->assign.l = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); + e = mkexpr(EXPRASSIGN, &typevoid); + e->assign.l = assignexpr(s); + if (e->assign.l->decayed) + e->assign.l = e->assign.l->base; + if (e->assign.l->type != &typevalist) + error(&tok.loc, "va_copy destination must have type va_list"); expect(TCOMMA, "after target va_list"); - e->assign.r = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); - e = exprconvert(e, &typevoid); + e->assign.r = assignexpr(s); + if (e->assign.r->decayed) + e->assign.r = e->assign.r->base; + if (e->assign.r->type != &typevalist) + error(&tok.loc, "va_copy source must have type va_list"); break; case BUILTINVAEND: + e = assignexpr(s); + if (e->decayed) + e = e->base; + if (e->type != &typevalist) + error(&tok.loc, "va_end argument must have type va_list"); e = mkexpr(EXPRBUILTIN, &typevoid); e->builtin.kind = BUILTINVAEND; - exprconvert(assignexpr(s), &typevalistptr); break; case BUILTINVASTART: e = mkexpr(EXPRBUILTIN, &typevoid); e->builtin.kind = BUILTINVASTART; - e->base = exprconvert(assignexpr(s), &typevalistptr); + e->base = mkunaryexpr(TBAND, assignexpr(s)); + if (e->base->base->type != &typevalist) + error(&tok.loc, "va_start argument must have type va_list"); expect(TCOMMA, "after va_list"); param = assignexpr(s); if (param->kind != EXPRIDENT) |