scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit f7b3cb04badaa5b42b9f0af83af837ab32b0336b
parent 5a7f4ee3d6a0643520098f73ecb93b4202bb5133
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 26 Sep 2015 10:24:18 +0200

Add calls to vararg functions

When a vararg is found in a call then the type check is disabled
and float are converted to double, and integer promotion is done.

Diffstat:
Mcc1/expr.c | 24+++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/cc1/expr.c b/cc1/expr.c @@ -535,7 +535,7 @@ arguments(Node *np) int toomany;; TINT n; Node *par = NULL, *arg; - Type **targs, *tp = np->type; + Type *argtype, **targs, *tp = np->type; if (tp->op == PTR && tp->type->op == FTN) { np = content(OPTR, np); @@ -554,18 +554,36 @@ arguments(Node *np) do { arg = decay(assign()); + argtype = *targs; + if (argtype == ellipsistype) { + n = 0; + switch (arg->type->op) { + case INT: + arg = promote(arg); + break; + case FLOAT: + if (arg->type == floattype) + arg = convert(arg, doubletype, 1); + break; + } + if (arg->type->op == INT) + arg = promote(arg); + par = node(OPAR, arg->type, par, arg); + continue; + } if (--n < 0) { if (!toomany) errorp("too many arguments in function call"); toomany = 1; continue; } - if ((arg = convert(arg, *targs++, 0)) != NULL) { + ++targs; + if ((arg = convert(arg, argtype, 0)) != NULL) { par = node(OPAR, arg->type, par, arg); continue; } errorp("incompatible type for argument %d in function call", - tp->n.elem - n + 1); + tp->n.elem - n + 1); } while (accept(',')); no_pars: