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!linus!decvax!ittvax!dcdwest!sdcsvax!sdcrdcf!hplabs!utah-cs!donn From: donn@utah-cs.UUCP Newsgroups: net.lang.c,net.bugs.4bsd Subject: Re: Parenthesis error in 4.2bsd c compiler [includes apologies] Message-ID: <3014@utah-cs.UUCP> Date: Wed, 29-Aug-84 00:11:35 EDT Article-I.D.: utah-cs.3014 Posted: Wed Aug 29 00:11:35 1984 Date-Received: Thu, 30-Aug-84 11:00:58 EDT References: <4894@root44.UUCP> Organization: University of Utah CS Dept Lines: 107 Shot my mouth off again... There is a terrible error in the fix I suggested for the float to int cast bug which I sent out earlier. The cure was worse than the disease... The compiler failed to make sure that the new treatment was being applied only to constants; it was throwing expressions and variables away! Fortunately the compiler detects the inconsistency and bitches about it. Here is (with crossed fingers) the correct fix, in clocal() in pcc/local.c: ------------------------------------------------------------------------ *** /tmp/,RCSt1024490 Wed Aug 29 00:25:09 1984 --- local.c Wed Aug 29 00:22:25 1984 *************** *** 85,91 case SCONV: m = (p->in.type == FLOAT || p->in.type == DOUBLE ); ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE ); ! if( m != ml ) break; /* now, look for conversions downwards */ --- 85,99 ----- case SCONV: m = (p->in.type == FLOAT || p->in.type == DOUBLE ); ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE ); ! if ( p->in.left->in.op == FCON && ml && !m ) { ! /* float type to int type */ ! r = block( ICON, NULL, NULL, INT, 0, 0 ); ! r->tn.lval = (int) p->in.left->fpn.dval; ! r->tn.rval = NONAME; ! p->in.left->in.op = FREE; ! p->in.left = r; ! } ! else if ( ml != m ) break; /* now, look for conversions downwards */ ------------------------------------------------------------------------ This will teach me to release a fix without testing it on something big... I DID remember to test the new compiler after installing the update, and tested it again after (recklessly?) installing the next fix. Speaking of which... Alain Williams provides a program which the 4.2 BSD C compiler generates incorrect code for: ------------------------------------------------------------------------ main() { unsigned u, u2; int m_7 = -7, two = 2, i, j; u = m_7; i = (u % two); j = ((int) u) % two; printf("%u %d %d %d %d\n", u, (int) (u%two), i, (u%two), j); } ------------------------------------------------------------------------ When run this program prints 4294967289 -1 1 1 -1 when it should print 4294967289 1 1 1 -1 instead. The problem is in the routine hardops() which finds unsigned division and remainder operations and replaces them with calls to subroutines. It should be looking at the types of the operands to determine if unsigned arithmetic is necessary, but it instead considers the type of the operator, which in this case was changed by a cast. The following change to hardops() in pcc/local2.c fixes this problem: ------------------------------------------------------------------------ *** /tmp/,RCSt1024433 Wed Aug 29 00:15:59 1984 --- local2.c Tue Aug 28 22:32:43 1984 *************** *** 1041,1048 register TWORD t; o = p->in.op; ! t = p->in.type; ! if( t!=UNSIGNED && t!=ULONG ) return; for( f=opfunc; f->fop; f++ ) { if( o==f->fop ) goto convert; --- 1041,1050 ----- register TWORD t; o = p->in.op; ! if( ! (optype(o)==BITYPE && ! (ISUNSIGNED(p->in.left->in.type) || ! ISUNSIGNED(p->in.right->in.type))) ) ! return; for( f=opfunc; f->fop; f++ ) { if( o==f->fop ) goto convert; ------------------------------------------------------------------------ Hope I don't have to backtrack again, 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