pme@EDDIE.MIT.EDU (Paul English x3168) (10/04/89)
I sent in this bug a few weeks ago, but now have more info from Kimbo Mundy (kimbo@ileaf.com). Thus I'll restate the bug. (And could you at least acknowledge receiving this bug report?) First, here is the program with the original description: -------------------- cut here -------------------- /* This program illustrates a bug in the gcc optimizer. * Execute the following: * gcc -g -O thisfile.c * a.out * face = 0 <incorrect> * gcc -O thisfile.c * a.out * face = 0 <incorrect> * gcc -g thisfile.c * face = 8 <correct> * (I did not try to get the absolutely minimal piece of code * that would recreate the problem.) * * The problem seems to be that the line: * new_ital = c & FN_ITALIC_FACE; * seems to be optimized away, along with the variable "new_ital". */ #define FID_FACE_SHIFT 8 #define FID_BOLD_FACE 0x00000100 #define FID_ITALIC_FACE 0x00000200 #define FN_BOLD_FACE (FID_BOLD_FACE >> FID_FACE_SHIFT) #define FN_ITALIC_FACE (FID_ITALIC_FACE >> FID_FACE_SHIFT) #define FN_BOLD_FACE_SAME 0L #define FN_BOLD_FACE_TOGGLE 1L #define FN_ITALIC_FACE_SAME 0L #define FN_ITALIC_FACE_TOGGLE (1L<<3) short bmodify; LoadFont(face) long face; { printf("face = %d\n", face); } short EcGetFontFamily( font) short font; { return 0; } short EcGetFontSize( font) short font; { return 10; } short EcGetFontFace( font) short font; { return (font == 0 ? 0 : FN_ITALIC_FACE); } void EcCmpnChangeDfont(new_font, delete_redundant) int new_font; short delete_redundant; { register short* cp; register short c; register short* end; register short new_change = -1, cur_font = -1; short change_to = -1; short old_font, old_fmly, old_size, old_bold, old_ital; short new_fmly, new_size, new_bold, new_ital; long face; register short* temp; if ( ( old_font = 0) == new_font ) return; bmodify += 1; new_fmly = EcGetFontFamily(new_font); new_size = EcGetFontSize(new_font); c = EcGetFontFace(new_font); new_bold = c & FN_BOLD_FACE; new_ital = c & FN_ITALIC_FACE; old_fmly = EcGetFontFamily(old_font); old_size = EcGetFontSize(old_font); c = EcGetFontFace(old_font); old_bold = c & FN_BOLD_FACE; old_ital = c & FN_ITALIC_FACE; face = ((new_bold^old_bold) ? FN_BOLD_FACE_TOGGLE : FN_BOLD_FACE_SAME)| ((new_ital^old_ital) ? FN_ITALIC_FACE_TOGGLE : FN_ITALIC_FACE_SAME); LoadFont(face); } main() { EcCmpnChangeDfont(1, 0); } -------------------- cut here -------------------- In combine.c:try_distrib, there is this comment: /* ??? Need to implement a test that PREV2 and PREV1 are completely independent. Right now their recognition ability is sufficiently limited that it should not be necessary, but better safe than sorry. */ I fear that this may be the source of the bug. In particular, it appears that the code is trying to distribute the ANDs through the XOR in the following lines from the above program: new_ital = c & FN_ITALIC_FACE; ... old_ital = c & FN_ITALIC_FACE; ... ((new_ital^old_ital) ? ... It decides it can do this and end up with (effectively): ((c ^ c) & FN_ITALIC_FACE) ? ... In essence, the lifetime information of c in the new_ital line is lost.