Article View: gnu.gcc.bug
Article #1077gcc 2.2.2 stdarg/varargs bug on hp9k7xx-hpux (with patch)
From: Bernd Anhaeupl
Date: Mon, 07 Sep 1992 13:19
Date: Mon, 07 Sep 1992 13:19
198 lines
6367 bytes
6367 bytes
hpux-Version: 8.07
gcc-Version: 2.2.2
config: hp720-hpux
(with gas 1.36 from utah)
Problem: <stdarg.h> and <varargs.h> do not work
Example:
------------------------------------ cut here ----------------------------------
#ifdef STDARG
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <stdarg.h>
void t1(int n,...)
{
va_list args;
double fa1,fa2,fa3;
int a1,a2,a3;
fa1=fa2=fa3=a1=a2=a3=0;
va_start(args,n);
fa1=va_arg(args,double);
a1 =va_arg(args,int);
fa2=va_arg(args,double);
printf("varargs: (%d,%d,%d)[%g,%g,%g]\n",a1,a2,a3,fa1,fa2,fa3);
va_end(args);
}
int main()
{
t1(0,1.0,1,2.0);
printf("Hello, world!\ncos(0)=%f\n",cos(0));
return EXIT_SUCCESS;
}
#else
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <varargs.h>
void t1(va_alist)
va_dcl
{
va_list args;
double fa1,fa2,fa3;
int a1,a2,a3;
fa1=fa2=fa3=a1=a2=a3=0;
va_start(args);
a1 =va_arg(args,int);
fa1=va_arg(args,double);
fa2=va_arg(args,double);
a2 =va_arg(args,int);
fa3=va_arg(args,double);
printf("varargs: (%d,%d,%d)[%g,%g,%g]\n",a1,a2,a3,fa1,fa2,fa3);
va_end(args);
}
int main()
{
t1(1,1.0,2.0,2,3.0);
printf("Hello, world!\ncos(0)=%f\n",cos(0));
return EXIT_SUCCESS;
}
#endif
-------------------------------- cut here -----------------------------
Program output after compilation with gcc -g -DSTDARG test.c -lM:
without patch below (wrong) with patch below (correct)
----------------------------------- -----------------------------------
varargs: (1,0,0)[7.39631e+97,2,0] varargs: (1,0,0)[1,2,0]
Hello, world! Hello, world!
cos(0)=1.000000 cos(0)=1.000000
----------------------------------- -----------------------------------
program output after compilation with gcc -g test.c -lM:
without patch below (wrong) with patch below (correct)
------------------------------------ ------------------------------------
varargs: (1,2,0)[7.39631e+97,2,3] [varargs: (1,2,0)[1,2,3]
Hello, world! Hello, world!
cos(0)=1.000000 cos(0)=1.000000
------------------------------------ ------------------------------------
You see that gnus vararg stuff does not find floating point arguments passed
in registers.
Temporary Solution:
Replace va-hp800.h with
-----------------------------cut here ----------------------------------
/*
Patch for GNUs varargs/stdarg implementation on HP-UX 8.07
Bernd Anhdupl, LATE, Uni Erlangen, Germany 08/06/92
(anhaeupl@late.e-technik.uni-erlangen.de)
The following code seems to work. Note, that the HP-UX linker (ld)
can ensure (by generating extra code), that floating point arguments,
which are passed through floating point registers are copied to the
corresponding general registers. Therefore you must only generate the
proper code to store the general registers arg0...arg3 at the
corresponding stack positions.
*/
#if __GNUC__ > 1
typedef void* va_list;
# define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
# ifdef _STDARG_H
typedef struct
{
char *__va_stack_start; /* Real start of stack args. */
char *__va_int; /* Pointer to the general register */
/* args and stack. */
char *__va_float; /* Pointer to the fp register args. */
char *__va_double;
} __gnu_va_list;
/*
__builtin_saveregs should be rewritten, since it is not necessary to
store the floating point registers, if the functions .EXTERN statemant
is correct. (You have to tell the linker that the function expects the
arguments in general registers.)
*/
#define va_start(AP,LASTARG) ((AP) = ((__gnu_va_list *)__builtin_saveregs())->__va_int)
# else
extern void * __va_save();
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! Implementation (must be moved to libgcc.a): !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void *__va_save(int*arg0,int*arg1,int*arg2,int*arg3)
{
return arg0+1;
}
*/
#define va_alist __arg0,__arg1,__arg2,__arg3
#define va_dcl
/* since registers have no address, the following call ensures that
(general) register arguments are stored on the stack */
#define va_start(AP) ((AP) = __va_save(&__arg0,&__arg1,&__arg2,&__arg3))
# endif /* _STDARG_H */
#define va_arg(AP, TYPE) \
( ( (__va_rounded_size(TYPE) <= 8) \
? ( (AP)-= __va_rounded_size (TYPE), \
(__alignof__ (TYPE) > 4 \
? ((int)(AP) &= ~(0x7)) \
: 0)) \
: (int)((AP) -= sizeof (TYPE *))), \
( (__va_rounded_size(TYPE) <= 8) \
? *(TYPE *)(AP) \
: **(TYPE **)(AP)))
#define va_end(AP)
#else /* __GNUCC__ > 1 */
#error wrong gcc version
#endif /* __GNUCC__ > 1 */
------------------------------------ cut here ----------------------------------
and add the necessary function __va_save(int&,int&,int&,int&) (see comment above)
to libgcc.a
This patch also makes GNU's varargs/stdarg stuff compatible with HP's.
Bernd Anhdupl
(anhaeupl@late.e-technik.uni-erlangen.de)
ps: Does anybody have a patch for the ARGW4 bug?
Please respond via email!
(for example: the followin program
---------------------- cut here ------------------------
#include <stdio.h>
#include <stdlib.h>
void test(double x1,int x2, double x3)
{
printf("%g,%d,%g",x1,x2,x3);
}
int main(void)
{
test(1,2,3);
return EXIT_SUCCESS;
}
--------------------- cut here ------------------------
results in
-------------------------------------------------------
gcc -g test.c
/usr/tmp/cca21836.s:55:Illegal argument description: 4
-------------------------------------------------------
). Please respond via e-mail.
Technical Details
Message-ID:
<9209070919.AA21843@late.e-technik.uni-erlangen.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!late.e-technik.uni-erlangen.DE!anhaeuplShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!late.e-technik.uni-erlangen.DE!anhaeupl From: anhaeupl@late.e-technik.uni-erlangen.DE (Bernd Anhaeupl) Subject: gcc 2.2.2 stdarg/varargs bug on hp9k7xx-hpux (with patch) Message-ID: <9209070919.AA21843@late.e-technik.uni-erlangen.de> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Mon, 7 Sep 1992 13:19:46 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 201