[gnu.gcc.bug] bug in sparc gcc 1.32

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (01/07/89)

The following code causes gcc to abort.  This is gcc version 1.32 on a
Sun 4/110 running SunOS 4.0.

Tom Quinn                 Canadian Institute for Theoretical Astrophysics
trq@moose.cita.utoronto.ca
UUCP   - decvax!utgpu!moose!trq
BITNET - quinn@utorphys.bitnet
ARPA   - trq%moose.cita.toronto.edu@relay.cs.net

The compile:
gcc -g -v -O  -sun4 -c  miarc.c
gcc version 1.32
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ miarc.c /tmp/cca03569.cpp
GNU CPP version 1.32
 /usr/local/lib/gcc-cc1 /tmp/cca03569.cpp -quiet -dumpbase miarc.c -g -O -version -o /tmp/cca03569.s
GNU C version 1.32 (sparc) compiled by GNU C version 1.32.
gcc: Program cc1 got fatal signal 6.

The code:
------------------------------------------------------------------------
computeAngleFromPath (startAngle, endAngle, w, h, lenp, backwards)
	int	startAngle, endAngle;	 
	int	*lenp;
	int	backwards;
{
	double	len;
	double	t0, t1, x0, y0, x1, y1, sidelen;
	int	a, startq, endq, q;
	int	a0, a1;
	a0 = startAngle;
	a1 = endAngle;
	len = *lenp;
	if (backwards) {
		a0 = (64 * 360)  - a0;
		a1 = (64 * 360)  - a1;
	}
	if (a1 < a0)
		a1 += (64 * 360) ;
	startq = floor ((double) a0 / (90.0 * 64.0));
	endq = floor ((double) a1 / (90.0 * 64.0));
	a = a0;
	a0 = a0 - startq * 90 *64;
	a1 = a1 - endq * 90 * 64;
	for (q = startq; q <= endq && len > 0; ++q) {
		if (q == startq && a0 != 0) {
			t0 = (((double) (a0 + startq * 90 * 64)) / 64.0 * 3.14159265358979323846 /180.0) ;
			x0 = (double) w / 2 * cos (t0);
			y0 = (double) h / 2* sin (t0);
		} else {
			x0 = 0;
			y0 = 0;
			switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
			case 0: x0 = (double) w/2;	break;
			case 2:	x0 = - (double) w/2;	break;
			case 1:	y0 = (double) h/2;	break;
			case 3:	y0 = -(double) h/2;	break;
			}
		}
		if (q == endq) {
 			if (a1 == 0) {
				x1 = 0;
				y1 = 0;
				switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
				case 0: x1 = (double) w/2;	break;
				case 2:	x1 = - (double) w/2;	break;
				case 1:	y1 = (double) h/2;	break;
				case 3:	y1 = -(double) h/2;	break;
				}
			} else {
				t1 = (((double) (a1 + endq * 90 * 64)) / 64.0 * 3.14159265358979323846 /180.0) ;
				x1 = (double) w / 2 * cos(t1);
				y1 = (double) h / 2 * sin(t1);
			}
		} else {
			x1 = 0;
			y1 = 0;
			switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
			case 0:	y1 = (double) h/2;	break;
			case 2:	y1 = - (double) h/2;	break;
			case 1:	x1 = -(double) w/2;	break;
			case 3:	x1 = (double) w/2;	break;
			}
		}
		sidelen = sqrt ((x1-x0)*(x1-x0) + (y1-y0) * (y1-y0));
		if (sidelen >= len) {
			x1 = 0;
			y1 = 0;
			switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
			case 0:	y1 = (double) h/2;	break;
			case 2:	y1 = -(double) h/2;	break;
			case 1:	x1 = -(double) w/2;	break;
			case 3:	x1 = (double) w/2;	break;
			}
			sidelen = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
			y1 = y0 + (y1 - y0) * len / sidelen;
			x1 = x0 + (x1 - x0) * len / sidelen;
			if (x1 == (double) w/2 && y1 == 0)
				a1 = 0;
			else if (x1 == -(double) w/2 && y1 == 0)
				a1 = 180 * 64;
			else if (y1 == (double) h/2 && x1 == 0)
				a1 = 90 * 64;
			else if (y1 == -(double) h/2 && x1 == 0)
				a1 = 270 * 64;
			else {
				if (w == 0) {
					t1 = asin (y1 / ((double) h/2));
					switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
					case 1:
					case 2:
						t1 = 3.14159265358979323846  - t1;
					}
				} else if (h == 0) {
					t1 = acos (x1 / ((double) w/2));
					switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) ) {
					case 2:
					case 3:
						t1 = 2 * 3.14159265358979323846  - t1;
					}
 				} else {
					t1 = atan2 (y1 * w, x1 * h);
				}
				a1 = (t1 * 180/3.14159265358979323846 ) * 64.0;
				if (a1 < 0)
					a1 += (64 * 360) ;
			}
 			a1 -= ((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))  * 90 * 64;
			len = 0;
		} else
			len -= sidelen;
	}
	*lenp = len;
	a1 = a1 + (q-1) * (90*64);
	if (backwards)
		a1 = (64 * 360)  - a1;
	return a1;
}

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (02/02/89)

The following code is compiled incorrectly by gcc with the "-g -O"
options.  This is gcc version 1.32 on a Sun 4/110 running SunOs 4.0.
The problem is that at line 62 it uses a global symbol (_shrinkFactor)
as the destination of a "st" instruction.  However, st can only take
an immediate of 13 bits.  The global symbol is generally greater than
13 bits, gets truncated, and running the code causes a segmentation
fault.

Tom Quinn                 Canadian Institute for Theoretical Astrophysics
trq@moose.cita.utoronto.ca
UUCP   - decvax!utgpu!moose!trq
BITNET - quinn@utorphys.bitnet
ARPA   - trq%moose.cita.toronto.edu@relay.cs.net

The compile:
gcc -g -v -S -O  -sun4 -c  texx.c
gcc version 1.32
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ texx.c /tmp/cca27101.cpp
GNU CPP version 1.32
 /usr/local/lib/gcc-cc1 /tmp/cca27101.cpp -quiet -dumpbase texx.c -g -O -version -o texx.s
GNU C version 1.32 (sparc) compiled by GNU C version 1.32.

The offending assembly:
.stabn 68,0,62,LM21
LM21:
	tst %o0
	bne L5
	nop
	b L6
	mov 0,%o0
L5:
	call _atoi,0
	nop
L6:
	st %o0,[_shrinkFactor]  ! Segmentation fault here

The code:
------------------------------------------------------------------------
typedef struct _XDisplay {
	int fd;			 
} Display;
Display *XOpenDisplay();
char *XGetDefault();
char *XDisplayName();
unsigned long XBlackPixel();
extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];
extern int	dviHHMargin;
extern int	dviVVMargin;
extern int	dviDPI;
extern int      dviBlackness;
extern char	*ProgName;
extern int dviInit();
Display *DISP;
static int Leaves;
int shrinkFactor[2 ];
static int reverse = 0;
char *malloc(), *calloc(), *index();
int Black_Pixel = 0;
main(argc, argv)
    int argc;
    char **argv;
{
    char *display = 0 ;
    char *option;
    int bwidth = 2;
    char *fore_color;
    char *back_color;
    char *high_color;
    char *brdr_color;
    char *mous_color;
    double atof();
    char *getenv();
    ProgName = *argv;
    argv++;
    argc--;
    if ((DISP = XOpenDisplay(display)) == 0 ) {
	fprintf((&_iob[2]) , "[%s] Can't open display '%s'\n",
		ProgName, XDisplayName(display));
	exit(1);
    }
    Black_Pixel = XBlackPixel(DISP, 0);
    if ((option = XGetDefault(DISP, ProgName, "ReverseVideo")) &&
	strcmp(option, "on") == 0)
	reverse = 1;
    if (option = XGetDefault(DISP, ProgName, "BorderWidth"))
	bwidth = atoi(option);
    fore_color = XGetDefault(DISP, ProgName, "ForeGround");
    back_color = XGetDefault(DISP, ProgName, "BackGround");
    high_color = XGetDefault(DISP, ProgName, "Highlight");
    brdr_color = XGetDefault(DISP, ProgName, "Border");
    mous_color = XGetDefault(DISP, ProgName, "Mouse");
    option = XGetDefault(DISP, ProgName, "NormalShrink");
    shrinkFactor[0 ] = (option == 0) ? 0 : atoi(option);
    option = XGetDefault(DISP, ProgName, "LargeShrink");
    shrinkFactor[1 ]  = (option == 0) ? 0 : atoi(option);
    option = XGetDefault(DISP, ProgName, "Blackness");
    dviBlackness = (option == 0) ? 3  : atoi(option);
    option = XGetDefault(DISP, ProgName, "Leaves");
    Leaves = (option == 0) ? 0 : atoi(option);
    option = XGetDefault(DISP, ProgName, "Dpi");
    dviDPI = (option == 0) ? 300  : atoi(option);
    option = XGetDefault(DISP, ProgName, "TopMargin");
    dviVVMargin = (option == 0) ? 300   : atof(option) * dviDPI;
    option = XGetDefault(DISP, ProgName, "SideMargin");
    dviHHMargin = (option == 0) ? 300   : atof(option) * dviDPI;
    dviInit();
}