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]

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


 > 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.


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