scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 494b5e954619ec4212db5a08c3f3b355b8104785
parent 9ef71d0377a399f0e0c8e3bcfd47843fb5d66210
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Fri, 20 Feb 2026 09:32:02 +0100

cc1: Fix va_start() warning

The va_start() builtin was checking if the parameter actually received was the actual
last named parameter of a function with variable argument list, but it tried to get
the ellipsis type from the list of arguments itself, but the list of arguments only
has the named arguments, so it was not possible to match the ellipsis type. In order
to check that it is required to go to the list of argument types of the function type.

Diffstat:
Msrc/cmd/scc-cc/cc1/builtin.c | 5++++-
Atests/cc/error/0040-vararg.c | 40++++++++++++++++++++++++++++++++++++++++
Mtests/cc/error/scc-tests.lst | 1+
3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/cmd/scc-cc/cc1/builtin.c b/src/cmd/scc-cc/cc1/builtin.c @@ -74,10 +74,13 @@ builtin_va_start(Symbol *sym) if (!valid_va_list(ap->type) || !(last->sym->flags&SDECLARED)) goto error; + tp = curfun->type; for (p = curfun->u.pars; p && *p != last->sym; ++p) ; - if (!p || *p == NULL || p[1] == NULL || p[1]->type != ellipsistype) + if (!p || *p == NULL || p[1] != NULL || + tp->p.pars[tp->n.elem-1] != ellipsistype) { warn("second parameter of 'va_start' not last named argument"); + } tp = last->type; if (tp == booltype || diff --git a/tests/cc/error/0040-vararg.c b/tests/cc/error/0040-vararg.c @@ -0,0 +1,40 @@ +/* +PATTERN: +0040-vararg.c:23: warning: second parameter of 'va_start' not last named argument +0040-vararg.c:27: warning: 'fmt' defined but not used +. +*/ + +typedef __builtin_va_list __va_list; + +typedef __va_list va_list; + +#define va_start(ap, last) __builtin_va_start(ap, last) +#define va_end(ap) __builtin_va_end(ap) +#define va_copy(to, from) __builtin_va_copy(to, from) +#define va_arg(to, type) __builtin_va_arg(to, type) + + +void +die1(int id, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, id); + va_end(ap); +} + +void +die2(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + va_end(ap); +} + +int +main(void) +{ + return 0; +} diff --git a/tests/cc/error/scc-tests.lst b/tests/cc/error/scc-tests.lst @@ -37,3 +37,4 @@ 0037-pointer.c 0038-void.c 0039-struct.c +0040-vararg.c