This is the mail archive of the 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]

Re: egcs-980315, gen*.c system.h and fatal() using stdarg/varargs

 > From: Jeffrey A Law <>
 >   In message <>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, 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)
#  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:

  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

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.

Kaveh R. Ghazi			Project Manager / Custom Development		Icon CMT Corp.

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