M cc.h => cc.h +1 -1
@@ 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 */
M expr.c => expr.c +22 -7
@@ 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)
M type.c => type.c +5 -9
@@ 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 *