This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Bug 20375 - ia64 varadic regression
- From: Zack Weinberg <zack at codesourcery dot com>
- To: Nathan Sidwell <nathan at codesourcery dot com>
- Cc: Dave Korn <dave dot korn at artimi dot com>, "'Andrew Pinski'" <pinskia at physics dot uc dot edu>, "'Joseph S. Myers'" <joseph at codesourcery dot com>, "'Richard Henderson'" <rth at redhat dot com>, "'gcc'" <gcc at gcc dot gnu dot org>
- Date: Tue, 08 Mar 2005 10:25:17 -0800
- Subject: Re: Bug 20375 - ia64 varadic regression
- References: <SERRANOaGidX0UZ07MX00000014@SERRANO.CAM.ARTIMI.COM><422DE418.9060202@codesourcery.com>
Nathan Sidwell <nathan@codesourcery.com> writes:
> Dave Korn wrote:
>
>> There was under varargs, which didn't require to pass a named
>> argument to va_start; it's only with stdargs that it would be
>> impossible. I suspect that this is the underlying reason for the
>> code having developed this way: sometimes the first variadic arg is
>> the last named arg (stdargs), sometimes it is the first arg _after_
>> the last named arg.
This is exactly backward. See below.
> ah, yes, that explains the later comment
> /* Handle stdargs. LAST_NAMED is a slight mis-nomer; it's also true
> for the unnamed dummy argument following the last named argument.
> See ABI silliness wrt strict_argument_naming and NAMED_ARG. So
> we only want to do this when we get to the actual last named
> argument, which will be the first time LAST_NAMED gets set. */
> I was trying to work out what the 'unnamed dummy argument' was. As we
> no longer support varargs, this can be excised.
The way you wrote a variadic function definition under the original
K+R <varargs.h> was
variadic(va_alist)
va_dcl
{
}
which would expand to something like
variadic(va_alist)
int va_alist;
{
}
va_start() would then take the address of va_alist, which was equal to
the address of the true first parameter (we are talking VAX-era
everything-on-the-stack calling conventions here). So a variadic
function, to the compiler, appeared to have one named argument.
Now when someone tried to implement <varargs.h> compatibility for GCC,
back in the day, they had to do something to put the compiler on
notice that this was, in fact, a variadic function being defined here
(since they were trying to support more complex calling conventions by
then). So what GCC's varargs.h used to do with va_alist and va_dcl
was
variadic(__va_alist)
int __va_alist; ...
{
}
and the ellipsis had roughly the same effect that it did for a
variadic function defined to the <stdarg.h> convention. But note the
key difference: if this were a stdarg function, "int __va_alist" would
be a true, named argument to the function, and the variable, anonymous
arguments would start at position 2. It is a varargs function, so
"int __va_alist" is a dummy, and the anonymous arguments start at
position 1. This is what the comment above refers to. It's
inaccurate insofar as the dummy argument does actually have a name,
but I don't blame whoever wrote it for getting confused.
(I suspect that there was some attempt to support named arguments
before va_alist in varargs mode; hence the stuff about the dummy
argument coming after named arguments.)
It would certainly be nice to get rid of this mess, but Jim Wilson
expressed concerns last time it came up:
<http://gcc.gnu.org/ml/gcc-patches/2004-01/msg03213.html>
zw