shithub: scc

Download patch

ref: f7b3cb04badaa5b42b9f0af83af837ab32b0336b
parent: 5a7f4ee3d6a0643520098f73ecb93b4202bb5133
author: Roberto E. Vargas Caballero <[email protected]>
date: Sat Sep 26 06:24:18 EDT 2015

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.

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -535,7 +535,7 @@
 	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,6 +554,23 @@
 
 	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");
@@ -560,12 +577,13 @@
 			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: