From: ichou@amd-1s.hac.com (Ian Chou)
Subject: GNU C Compiler Bug
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sat, 5 Sep 1992 00:29:12 GMT

Author:  Ian D. Chou
e-mail:  ichou@amd-1s.hac.com

Machine type: Auspex Sparc
OS: Unix

gcc version 1.37.1
GNU CPP version 1.37.1
GNU C version 1.37.1 (68k, MIT syntax) compiled by CC.
default target switches: -m68020 -mc68020 -m68881 -mbitfield

Following is a source listing which exhibits a problem when compiling
structures containing bit fields with the -fvolatile option. Following
this is the assembly code generated for this C code. One listing is
with the -fvolatile flag (incorrect), and the last one is without the
flag (correct code). 


The -fvolatile flag causes the wrong assembler instruction to be
generated, when the field byteOffset is accessed, only the low order
byte is moved into a register but the upper 24 bits of that same
register is extracted and operated on.


EXAMPLE OF CODE WHICH DOES NOT WORK:
====================================

typedef struct _CharInfo {
    unsigned	byteOffset:24;	/* byte offset of the raster from pGlyphs */
    unsigned	exists:1;	/* true iff glyph exists for this char */
    unsigned	pad:7;		/* must be zero for now */
} CharInfoRec;

typedef struct _FontInfo {
    unsigned int	version1;   /* version stamp */
    unsigned int	allExist;
    unsigned int	drawDirection;
    unsigned int	noOverlap;	/* true if:
					 * max(rightSideBearing-characterWidth)
					 * <= minbounds->metrics.leftSideBearing
					 */
    unsigned int	constantMetrics;
    unsigned int        mcgFont;        /* AMD44 modification - when set to 
                                         * true it indicates that the font is
                                         * approved for loading into Display 
                                         * Memory. This field is set true or
                                         * false by the bdftosnf conversion
                                         * program and checked by the snffonts
                                         * server routine. 
                                         */
    unsigned int	terminalFont;	/* Should be deprecated!  true if:
					   constant metrics &&
					   leftSideBearing == 0 &&
					   rightSideBearing == characterWidth &&
					   ascent == fontAscent &&
					   descent == fontDescent
					*/
    unsigned int	linear:1;	/* true if firstRow == lastRow */
    unsigned int	constantWidth:1;  /* true if minbounds->metrics.characterWidth
					   *      == maxbounds->metrics.characterWidth
					   */
    unsigned int	inkInside:1;    /* true if for all defined glyphs:
					 * leftSideBearing >= 0 &&
					 * rightSideBearing <= characterWidth &&
					 * -fontDescent <= ascent <= fontAscent &&
					 * -fontAscent <= descent <= fontDescent
					 */
    unsigned int	inkMetrics:1;	/* ink metrics != bitmap metrics */
					/* used with terminalFont */
					/* see font's pInk{CI,Min,Max} */
    unsigned int	padding:28;
    unsigned int	firstCol;
    unsigned int	lastCol;
    unsigned int	firstRow;
    unsigned int	lastRow;
    unsigned int	nProps;
    unsigned int	lenStrings; /* length in bytes of string table */
    unsigned int	chDefault;  /* default character */ 
    int			fontDescent; /* minimum for quality typography */
    int			fontAscent;  /* minimum for quality typography */
    CharInfoRec		minbounds;  /* MIN of glyph metrics over all chars */
    CharInfoRec		maxbounds;  /* MAX of glyph metrics over all chars */
    unsigned int	pixDepth;   /* intensity bits per pixel */
    unsigned int	glyphSets;  /* number of sets of glyphs, for
					    sub-pixel positioning */
    unsigned int	version2;   /* version stamp double-check */
} FontInfoRec;

typedef struct _FontInfo *FontInfoPtr;

typedef struct _Font {
    FontInfoPtr	pFI;
} FontRec;

typedef struct _Font *FontPtr;

FontRec ACTUALFONT;
FontInfoRec ACTUALPFI;
unsigned int A;
main ()
{
  FontPtr pfont;

  pfont = &ACTUALFONT;
  pfont->pFI = &ACTUALPFI;
  A = (pfont->pFI->maxbounds.byteOffset + 3) & ~3;
}
----------------------------------------------------------------------------

COMPILED WITH -fvolatile flag : cc68k -c -g -O -fvolatile gnubug.c -S
==================================================================

#NO_APP
gcc_compiled.:
	.stabs "gnubug.c",100,0,0,Ltext
Ltext:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "void:t15=15",128,0,0,0
.stabs "_CharInfo:T16=s4byteOffset:1,0,24;exists:1,24,1;\\",128,0,0,0
.stabs "pad:1,25,7;;",128,0,0,0
.stabs "CharInfoRec:t16",128,0,0,0
.stabs "_FontInfo:T17=s88version1:4,0,32;allExist:4,32,32;\\",128,0,0,0
.stabs "drawDirection:4,64,32;noOverlap:4,96,32;constantMetrics:4,128,32;\\",128,0,0,0
.stabs "mcgFont:4,160,32;terminalFont:4,192,32;linear:1,224,1;\\",128,0,0,0
.stabs "constantWidth:1,225,1;inkInside:1,226,1;inkMetrics:1,227,1;\\",128,0,0,0
.stabs "padding:1,228,28;firstCol:4,256,32;lastCol:4,288,32;\\",128,0,0,0
.stabs "firstRow:4,320,32;lastRow:4,352,32;nProps:4,384,32;\\",128,0,0,0
.stabs "lenStrings:4,416,32;chDefault:4,448,32;fontDescent:1,480,32;\\",128,0,0,0
.stabs "fontAscent:1,512,32;minbounds:16,544,32;maxbounds:16,576,32;\\",128,0,0,0
.stabs "pixDepth:4,608,32;glyphSets:4,640,32;version2:4,672,32;;",128,0,0,0
.stabs "FontInfoRec:t17",128,0,0,0
.stabs "FontInfoPtr:t18=*17",128,0,0,0
.stabs "_Font:T19=s4pFI:18,0,32;;",128,0,0,0
.stabs "FontRec:t19",128,0,0,0
.stabs "FontPtr:t20=*19",128,0,0,0
.text
	.even
.globl _main
_main:
	.stabd 68,0,74
	link a6,#0
LBB2:
	.stabd 68,0,77
	lea _ACTUALFONT,a0
	.stabd 68,0,78
	movel #_ACTUALPFI,a0@
	.stabd 68,0,79
	movel a0@,a0
	moveb a0@(72),d0        ; This only moves the low order byte of the field
                                ; It should move all 32 bits before extracting
                                ; the upper 24 bits.
	bfextu d0{#0:#24},d0
	addql #3,d0
	moveq #-4,d1
	andl d1,d0
	movel d0,_A
LBE2:
	.stabd 68,0,80
	unlk a6
	rts
.stabs "main:F1",36,0,0,_main
.stabs "pfont:r20",64,0,0,8
.stabn 192,0,0,LBB2
.stabn 224,0,0,LBE2
.stabs "A:G4",32,0,0,0
.comm _A,4
.stabs "ACTUALPFI:G17",32,0,0,0
.comm _ACTUALPFI,88
.stabs "ACTUALFONT:G19",32,0,0,0
.comm _ACTUALFONT,4

------------------------------------------------------------------------

COMPILED WITHOUT -fvolatile: cc68k -c -g -O gnubug.c -S
====================================================

#NO_APP
gcc_compiled.:
	.stabs "gnubug.c",100,0,0,Ltext
Ltext:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "void:t15=15",128,0,0,0
.stabs "_CharInfo:T16=s4byteOffset:1,0,24;exists:1,24,1;\\",128,0,0,0
.stabs "pad:1,25,7;;",128,0,0,0
.stabs "CharInfoRec:t16",128,0,0,0
.stabs "_FontInfo:T17=s88version1:4,0,32;allExist:4,32,32;\\",128,0,0,0
.stabs "drawDirection:4,64,32;noOverlap:4,96,32;constantMetrics:4,128,32;\\",128,0,0,0
.stabs "mcgFont:4,160,32;terminalFont:4,192,32;linear:1,224,1;\\",128,0,0,0
.stabs "constantWidth:1,225,1;inkInside:1,226,1;inkMetrics:1,227,1;\\",128,0,0,0
.stabs "padding:1,228,28;firstCol:4,256,32;lastCol:4,288,32;\\",128,0,0,0
.stabs "firstRow:4,320,32;lastRow:4,352,32;nProps:4,384,32;\\",128,0,0,0
.stabs "lenStrings:4,416,32;chDefault:4,448,32;fontDescent:1,480,32;\\",128,0,0,0
.stabs "fontAscent:1,512,32;minbounds:16,544,32;maxbounds:16,576,32;\\",128,0,0,0
.stabs "pixDepth:4,608,32;glyphSets:4,640,32;version2:4,672,32;;",128,0,0,0
.stabs "FontInfoRec:t17",128,0,0,0
.stabs "FontInfoPtr:t18=*17",128,0,0,0
.stabs "_Font:T19=s4pFI:18,0,32;;",128,0,0,0
.stabs "FontRec:t19",128,0,0,0
.stabs "FontPtr:t20=*19",128,0,0,0
.text
	.even
.globl _main
_main:
	.stabd 68,0,74
	link a6,#0
LBB2:
	.stabd 68,0,77
	.stabd 68,0,78
	movel #_ACTUALPFI,_ACTUALFONT
	.stabd 68,0,79
	bfextu _ACTUALPFI+72{#0:#24},d0
	addql #3,d0
	moveq #-4,d1
	andl d1,d0
	movel d0,_A
LBE2:
	.stabd 68,0,80
	unlk a6
	rts
.stabs "main:F1",36,0,0,_main
.stabn 192,0,0,LBB2
.stabn 224,0,0,LBE2
.stabs "A:G4",32,0,0,0
.comm _A,4
.stabs "ACTUALPFI:G17",32,0,0,0
.comm _ACTUALPFI,88
.stabs "ACTUALFONT:G19",32,0,0,0
.comm _ACTUALFONT,4


Newsgroups: gnu.gcc.bug