i = i * f vs. i *= f

Chuck Privitera crp at ccivax.UUCP
Thu Apr 19 00:40:39 AEST 1984


The bug was reported (and fixed) back in January by randvax!edhall.
I have installed the fix here and have not had any problems since.
The fix follows:


>From ritcv!rochester!seismo!hao!hplabs!sdcrdcf!randvax!edhall Wed Jan 11 03:13:26 1984
Subject: integer op= floating evaluated incorrectly by C compiler
Newsgroups: net.bugs.4bsd,net.bugs.usg

------------------------------------
This bug may affect all pre-5.0USG C compilers, and perhaps earlier
5.0USG compilers as well.  The below fix only works for PCC-derived
compilers (such as the BSD VAX C compiler).

Index:  usr.lib/ccom 4.2BSD 4.1BSD 3.0USG

Description:
	When assignement operators such as *= are used with an integer
	Left-Hand Side and a floating-point expression on the Right-
	Hand Side, results are incorrect.  For example:

		int i = 6;
		i *= .5;

	leaves a value of 0 in i, rather than 3.  The +=, -=, and /=
	operators are similarly affected.

Caused by:
	Conversion of RHS of assignment to type of LHS before application
	of the operator.

Fixed by:
	The fix is in two parts.  First, the automatic forcing of type
	conversion to the LHS of an assignment op must be shut off in
	appropriate circumstances.  This requires a change to tymatch()
	in mip/trees.c:

1031c1031,1035
< 	if( t != t2 || o==CAST ) p->in.right = makety( p->in.right, tu, 0, (int)tu );
---
> 	if( o==CAST || (t != t2
> 	  && ( (dope[o]&(FLOFLG|ASGOPFLG)) != (FLOFLG|ASGOPFLG)
> 	  || t != INT || (t2 != DOUBLE && t2 != FLOAT) )) ) {
> 		p->in.right = makety( p->in.right, tu, 0, (int)tu );
> 		}

	This causes certain assignment ops (+=, -=, *=, /=, i.e. the ones
	appropriate in floating-point) to remain in the parse tree without
	`balanced' operand types.  When these get to code-generation the
	compiler would break unless the template table had the proper pieces
	added to it.  Thus, in pcc/table.c:

712a713,729
>
> /* begin new stuff */
>
> ASG OPFLOAT,    INAREG|FOREFF|FORCC,
>       SAREG|AWD,      TWORD|TCHAR|TSHORT,
>       SAREG|AWD,      TDOUBLE,
>               NAREG,  RLEFT|RESCC,
>               "       cvtZLd  AL,A1\n OD2     AR,A1\n cvtdZL  A1,AL\n",
>
> ASG OPFLOAT,    INAREG|FOREFF|FORCC,
>       SAREG|AWD,      TWORD|TCHAR|TSHORT,
>       SAREG|AWD,      TFLOAT,
>               NAREG,  RLEFT|RESCC,
>               "       cvtZLf  AL,A1\n OF2     AR,A1\n cvtfZL  A1,AL\n",
>
> /* end new stuff */
>

	-Ed Hall
	Rand Corporation
	Santa Monica, CA
	decvax!randvax!edhall   (UUCP)
	edhall at rand-unix        (ARPA)

There are plenty of parenthesis to miss there. Be careful!

				Chuck



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