Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site utah-cs.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxl!houxm!hogpc!houti!ariel!vax135!cornell!uw-beaver!tektronix!hplabs!utah-cs!donn From: donn@utah-cs.UUCP Newsgroups: net.lang.c,net.bugs.4bsd Subject: Re: C compiler bug (I think). [Contains fix] Message-ID: <3009@utah-cs.UUCP> Date: Sat, 25-Aug-84 08:38:16 EDT Article-I.D.: utah-cs.3009 Posted: Sat Aug 25 08:38:16 1984 Date-Received: Thu, 30-Aug-84 06:35:12 EDT References: <73@ur-valhalla.UUCP> <8164@umcp-cs.UUCP> Organization: University of Utah CS Dept Lines: 82 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@utah-cs.arpa 40 46' 6"N 111 50' 34"W (801) 581-5668 decvax!utah-cs!donn