Parenthesis error in 4.2bsd c compiler [includes apologies]
donn at utah-cs.UUCP
donn at utah-cs.UUCP
Wed Aug 29 14:11:35 AEST 1984
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 at utah-cs.arpa
40 46' 6"N 111 50' 34"W (801) 581-5668 decvax!utah-cs!donn
More information about the Comp.lang.c
mailing list