C compiler bug (I think). [Contains fix]

donn at utah-cs.UUCP donn at utah-cs.UUCP
Sat Aug 25 22:38:16 AEST 1984


To recap:  The following program blows up the 4.2 (== System III?)
C compiler:

------------------------------------------------------------------------
int one = (unsigned) 2 >> 1;
------------------------------------------------------------------------

The precise message you get is:

------------------------------------------------------------------------
"one.c", line 1: compiler error: expression causes compiler loop: try simplifying
------------------------------------------------------------------------

Chris Torek's observation is close to the mark (if not on it), but
perhaps it's not as clear as it could be.  The problem is that the
initializer is not being reduced to a constant before the code
generator receives it.  If the code generator gets an expression, it
goes ahead and generates the instructions needed to compute it;
apparently it doesn't mind if it ends up generating instructions into
data space, nor does it seem to care if any of the startup code for
processing text has been run.  The code generator can handle constant
initializers (with a fake opcode of INIT) and that's it.

More directly, what's happening is that when certain casts are
transmuted into conversions, the compiler neglects to canonicalize the
resulting trees.  (Some casts get a second chance -- try substituting
'+' for '<<' in the example and see what happens.) It's a fairly simple
matter to ensure that makety(), the routine which does the
transmutations, always canonicalizes the trees it returns.  Here are
the changes to /usr/src/lib/mip/trees.c:

------------------------------------------------------------------------
*** /tmp/,RCSt1008238	Sat Aug 25 06:30:16 1984
--- trees.c	Sat Aug 25 04:37:26 1984
***************
*** 1061,1067
  
  	if( t & TMASK ){
  		/* non-simple type */
! 		return( block( PCONV, p, NIL, t, d, s ) );
  		}
  
  	if( p->in.op == ICON ){

--- 1061,1067 -----
  
  	if( t & TMASK ){
  		/* non-simple type */
! 		return( clocal( block( PCONV, p, NIL, t, d, s ) ) );
  		}
  
  	if( p->in.op == ICON ){
***************
*** 1079,1085
  			}
  		}
  
! 	return( block( SCONV, p, NIL, t, d, s ) );
  
  	}
  

--- 1079,1085 -----
  			}
  		}
  
! 	return( clocal( block( SCONV, p, NIL, t, d, s ) ) );
  
  	}
  
------------------------------------------------------------------------

I'm not sure that the first change is strictly necessary, but better
safe than sorry.  At any rate the sample program now compiles
correctly.  I don't think these changes have any nasty side effects --
I recompiled the compiler with the changes installed and it produced
exactly the same binary as the old compiler did, for what it's worth.

If the System V C compiler fixes this, I don't want to hear about it,

Donn Seeley    University of Utah CS Dept    donn at utah-cs.arpa
40 46' 6"N 111 50' 34"W    (801) 581-5668    decvax!utah-cs!donn



More information about the Comp.bugs.4bsd.ucb-fixes mailing list