home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.gcc.bug
- Path: sparky!uunet!ferkel.ucsb.edu!taco!rock!stanford.edu!agate!usenet.ins.cwru.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!tera.com!rrh
- From: rrh@tera.com (Robert R. Henry)
- Subject: sparc va_arg botches some structure passing
- Message-ID: <9211172006.AA11270@tera.com>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Tue, 17 Nov 1992 20:06:47 GMT
- Approved: bug-gcc@prep.ai.mit.edu
- Lines: 93
-
- The following program contains a varargs routine,
- which is given a 32 bit structure by value in one
- of the varargs slots.
-
- It is compiled by BOTH gcc2.3.1 and gcc2.2.2, host=sparc, target=sparc.
-
- When the resulting code is executed it bus errors at the line marked ``HERE''.
- Examining the faulting instruction shows that it is executing
- ld [%o1], %o0
- with o1 containing 113. The value 113 is what the va_arg
- should ultimately deliver; there's one too many indirections going on.
-
- This situation happens even if the structure actual parameter
- is the first actual parameter after the 'op' parameter (so
- its unlikely to be a register window alignment problem, altho
- one never knows).
-
- #include <stdio.h>
- #include <stdarg.h>
-
- typedef int TERA_Boolean;
-
- typedef enum _FullEmptyControl{
- FE_NORMAL = 0
- ,FE_FUTURE = 2
- ,FE_SYNC = 3
- } FullEmptyControl;
-
- typedef struct _OperationAccessControl{
- int :27 ;
- TERA_Boolean fwd_disable :1 ;
- FullEmptyControl fe_control :2 ;
- TERA_Boolean trap1_disable :1 ;
- TERA_Boolean trap0_disable :1 ;
- } OperationAccessControl;
-
- typedef long long int int64;
-
- void encode(int64 *r_result, int op, ...)
- {
- static int v[] = {
- 0,
- 1, 1, 2,
- 3, 2, -1
- };
- int64 result;
- int shift_amt = 64;
- int iarg;
- int shift = 0;
- int pass_op;
- unsigned int uarg;
- int type;
- int optype;
- int save_low_offset;
- va_list ap;
- va_start(ap, op);
-
- for (iarg = 0; v[iarg] >= 0; iarg++){
- switch(v[iarg]){
- case 0: /* begin */
- printf("begin\n");
- break;
- case 1: /* reg */
- uarg = va_arg(ap, unsigned int);
- printf("reg %d\n", uarg);
- break;
- case 2: /* lit */
- printf("lit\n");
- break;
- case 3: /* UnsOpAC */
- {
- union {
- OperationAccessControl ac;
- int prt;
- } ac_ctrl;
- OperationAccessControl acl;
- /* BUS ERROR HERE */
- acl = va_arg(ap, OperationAccessControl);
- printf("oac %d\n", ac_ctrl.prt);
- break;
- }
- default:
- break;
- }
- }
- }
-
- main()
- {
- int64 x;
- encode(&x, 0, 17, 18, 113, 117);
- }
-
-