shithub: scc

Download patch

ref: 0049d447d0d28b28389342299fde625823cd34fa
parent: 8533b9940b37a8939ca2af338d28f5ae17b1b4ce
author: Roberto E. Vargas Caballero <[email protected]>
date: Mon Feb 13 11:58:29 EST 2017

[cc1] Add warnings in builtin_va_start()

There are a lot of strange conditions in va_start()
that should be informed as warnings to the user,
because any of them can generate wrong code in
some implementations/architectures.

--- a/cc1/builtin.c
+++ b/cc1/builtin.c
@@ -18,7 +18,7 @@
 
 	if (!valid_va_list(ap->type)) {
 		errorp("incorrect parameters for va_arg");
-		return constnode(zero);
+		goto error;
 	}
 	if (tp == booltype ||
 	    tp == chartype || tp == uchartype || tp == schartype ||
@@ -30,6 +30,9 @@
 	np = node(OBUILTIN, tp, ap, NULL);
 	np->sym = sym;
 	return np;
+
+error:
+	return constnode(zero);
 }
 
 static Node *
@@ -55,16 +58,31 @@
 builtin_va_start(Symbol *sym)
 {
 	Node *np, *ap, *last;
+	Symbol **p, *lastsym;
+	Type *tp;
 
 	ap = assign();
 	expect(',');
 	if (yytoken != IDEN)
 		goto error;
-	last = varnode(yylval.sym);
+	lastsym = yylval.sym;
+	last = varnode(lastsym);
 	next();
 
-	if (!valid_va_list(ap->type))
-		goto error;
+	if (!valid_va_list(ap->type) || !(lastsym->flags&SDECLARED))
+		 goto error;
+
+	for (p = curfun->u.pars; p && *p != lastsym; ++p)
+		/* nothing */;
+	if (!p || *p == NULL || p[1] == NULL || p[1]->type != ellipsistype)
+		warn("second parameter of 'va_start' not last named argument");
+
+	tp = last->type;
+	if (tp == booltype ||
+	    tp == chartype || tp == uchartype || tp == schartype ||
+	    tp == shortype || tp == ushortype) {
+		warn("last parameter before '...' must not be bool, char or short");
+	}
 
 	np = node(OBUILTIN, voidtype, ap, last);
 	np->sym = sym;
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -470,8 +470,6 @@
 	for (sp = sym->u.pars; sp && *sp; ++sp)
 		emit(ODECL, *sp);
 	fputs("\\\n", outfp);
-	free(sym->u.pars);
-	sym->u.pars = NULL;
 }
 
 static void
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -901,6 +901,8 @@
 	compound(NULL, NULL, NULL);
 	popctx();
 	emit(OEFUN, NULL);
+	free(sym->u.pars);
+	sym->u.pars = NULL;
 	flushtypes();
 	curfun = ocurfun;
 }