From 16c718729adfaf40cf22aa4efeafb0d92ef5ee3c Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sat, 4 Sep 2021 13:43:16 -0700 Subject: Prepare for supporting architecture-specific va_list type --- cc.h | 2 +- expr.c | 29 ++++++++++++++++++++++------- type.c | 14 +++++--------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/cc.h b/cc.h index 3b33e8c..9c4484b 100644 --- a/cc.h +++ b/cc.h @@ -428,7 +428,7 @@ extern struct type typeint, typeuint; extern struct type typelong, typeulong; extern struct type typellong, typeullong; extern struct type typefloat, typedouble, typeldouble; -extern struct type typevalist, typevalistptr; +extern struct type typevalist; /* targ */ diff --git a/expr.c b/expr.c index 70aa3bd..6837adb 100644 --- a/expr.c +++ b/expr.c @@ -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) diff --git a/type.c b/type.c index f58247a..a97175a 100644 --- a/type.c +++ b/type.c @@ -39,17 +39,13 @@ struct type typefloat = FLTTYPE(TYPEFLOAT, 4); struct type typedouble = FLTTYPE(TYPEDOUBLE, 8); struct type typeldouble = FLTTYPE(TYPELDOUBLE, 16); -static struct type typevaliststruct = { - .kind = TYPESTRUCT, .size = 32, .align = 8, - .prop = PROPOBJECT|PROPAGGR, -}; struct type typevalist = { - .kind = TYPEARRAY, .size = 32, .align = 8, .array = {1}, .base = &typevaliststruct, + .kind = TYPEARRAY, .size = 32, .align = 8, .array = {1}, .prop = PROPOBJECT|PROPDERIVED|PROPAGGR, -}; -struct type typevalistptr = { - .kind = TYPEPOINTER, .size = 8, .align = 8, .base = &typevaliststruct, - .prop = PROPOBJECT|PROPDERIVED|PROPSCALAR, + .base = &(struct type){ + .kind = TYPESTRUCT, .size = 32, .align = 8, + .prop = PROPOBJECT|PROPAGGR, + }, }; struct type * -- cgit v1.2.3