This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: egcs-980315, gen*.c system.h and fatal() using stdarg/varargs
- To: law at cygnus dot com
- Subject: Re: egcs-980315, gen*.c system.h and fatal() using stdarg/varargs
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Date: Tue, 24 Mar 1998 12:50:32 -0500 (EST)
- Cc: egcs at cygnus dot com, ghazi at caip dot rutgers dot edu
> From: Jeffrey A Law <law@hurl.cygnus.com>
>
> In message <199803200208.VAA11947@caip.rutgers.edu>you write:
> > Here is my patch to add system.h to gen*.c. It also fixes the
> > static function `fatal' to use real variable argument parameter lists.
> >
> > Is so doing, I uncovered some format specifier problems in
> > genattrtab.c:
> >
> > > ./genattrtab.c:979: warning: char format, rtx_def arg (arg 2)
> > > ./genattrtab.c:984: warning: char format, rtx_def arg (arg 2)
> > > ./genattrtab.c:1001: warning: char format, rtx_def arg (arg 2)
> > > ./genattrtab.c:1012: warning: char format, rtx_def arg (arg 2)
> > > ./genattrtab.c:1012: warning: char format, rtx_def arg (arg 3)
> >
> > All of these cases appear to be using a %s to print a XEXP(rtx,N).
> > Should these instead be changed to %s and XSTR(rtx,N) ?
> Hard to be sure since the line #s do not match what's currently in
> the sources.
>
> I see 5 cases in "check_attr_test" which appear to fit the description
> you've given. Those should be using XSTR, not XINT as you suspected.
Yes, the ones in check_attr_test are them. I should have
specified the function name. Thanks.
> For the "fatal" problem -- I don't think you can rely on having
> vfprintf. You have to check for it. If you don't have it, you'll
> probably have to punt back to extracting the args as ints and
> passing them to fprintf.
>
Well, that gets kind of gross. You then have four cases which
you have to intricately ifdef you way around inside the function. Ie,
the cross product of __STDC__ (yes/no) and HAVE_VPRINTF (yes/no). If
we go this route, I'd like to come of with a generalized workable
solution we can use across the board. (See below.)
The gcc source is inconsistent in this regard. Eg, files like
cccp.c/cexp.c handle missing vfprintf by sucking arguments out using
va_arg() and then calling fprintf. To me it seems that if vfprintf is
missing, it is a dubious proposition to assume varargs.h/va_arg() are
present. Though gcc does exactly that and it seems to work. (Are
there any known platforms which fit this description, missing vfprintf
but have varargs.h/va_arg()?) The file toplev.c does something
similar. But gcc.c is different, it uses vfprintf, but falls back on
using ints if vfprintf is not available. And as we know, the gen*.c
files hardwire always using integers.
Note that if we implement the macro idea I proposed in
http://www.cygnus.com/ml/egcs/1998-Feb/1155.html, then this issue goes
away except where we have to pass a function pointer (which does come
up in the gcc source, but not in gen*.c.) Just a thought.
Another thing we can do is put the following in system.h:
#if !defined(HAVE_VPRINTF) && !defined(vfprintf)
# ifdef HAVE_DOPRNT
# define vfprintf(stream, format, args) _doprnt(format, args, stream)
# else
# define vfprintf(stream, format, args) \
do { \
HOST_WIDE_INT a0 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a1 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a2 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a3 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a4 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a5 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a6 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a7 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a7 = va_arg(args, HOST_WIDE_INT); \
HOST_WIDE_INT a9 = va_arg(args, HOST_WIDE_INT); \
fprintf (stream, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); \
} while (0)
# endif /* HAVE_DOPRNT */
#endif /* ! defined(HAVE_VPRINTF) && ! defined(vfprintf) */
This should allow us to use vfprintf with impunity, iff we
assume we can always fall back on varargs.h/va_arg().
The third thing we can do is when neither stdarg.h or varargs.h are
available, then we do:
# define va_alist format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9
# define va_dcl char *format, *a0, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
and then the following works:
fatal(va_alist)
va_dcl
{
blah; ...
fprintf(stderr, va_alist);
blah; ...
}
Its actually more complicated than this, but you get the idea.
Anyway, let's please arrive at a consensus so I can implement something
which you'll approve for installation.
1. Use macros for function fatal which call fprintf. (See
http://www.cygnus.com/ml/egcs/1998-Feb/1155.html)
2. Use stdarg/varargs in function fatal which always call vfprintf
and define vfprintf to something if its not available.
3. Add a fall back case which defines va_alist/va_dcl and calls
fprintf when stdarg/varargs and vfprintf are not available.
4. Some combination of the above.
5. Some yet to be mentioned option.
Thanks,
--Kaveh
--
Kaveh R. Ghazi Project Manager / Custom Development
ghazi@caip.rutgers.edu Icon CMT Corp.