🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #1422

sparc va_arg botches some structure passing

#1422
From: Robert R. Henry
Date: Tue, 17 Nov 1992 20:06
92 lines
2596 bytes
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);
}
Technical Details
Message-ID: <9211172006.AA11270@tera.com>
Path: arc1-ca.pugleaf.net!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

Show Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug
Path: arc1-ca.pugleaf.net!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