This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug 20375 - ia64 varadic regression


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]