4bsd-f77@utah-cs.UUCP (4.2 BSD f77 bug reports) (09/10/84)
From: Donn Seeley <donn@utah-cs.arpa> Subject: F77 scrambles the cmplx() intrinsic function Index: usr.bin/f77/src/f77pass1/expr.c 4.2BSD Description: F77 mutilates expressions that use the intrinsic function cmplx() to convert two REAL or DOUBLE PRECISION values into a COMPLEX value. In particular the imaginary part of the value is lost. This bug was found by lanl-a!pam (whose real name I never seem to have discovered). Repeat-By: Compile the following program from lanl-a!pam: ---------------------------------------------------------------- complex a, b a = (1.0, 2.0) b = cmplx (abs(real(a)), abs(imag(a))) print *, a, b stop end ---------------------------------------------------------------- When run it prints: ---------------------------------------------------------------- ( 1.00000, 2.00000) ( 1.00000, 0.) ---------------------------------------------------------------- It's supposed to print: ---------------------------------------------------------------- ( 1.00000, 2.00000) ( 1.00000, 2.00000) ---------------------------------------------------------------- Fix: The problem is that fixexpr(), the routine which handles the manipulation and checking of expression trees, does not know about complex conversions with two operands. This might be okay if it just left trees like this alone, but it has an optimization it wants to try and of course it amputates the imaginary part of the conversion when it rewrites the tree. In general the compiler does not seem well equipped to deal with complex conversions with two operands -- I wouldn't be surprised if there were more bugs of this sort. The following changes to fixexpr() and cktype() in expr.c stop the butchery, for at least the example program: ---------------------------------------------------------------- *** /tmp/,RCSt1029508 Mon Aug 20 20:48:32 1984 --- expr.c Sun Aug 5 23:06:34 1984 *************** *** 659,664 case OPCONV: ptype = cktype(OPCONV, p->vtype, ltype); if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA) { --- 663,675 ----- case OPCONV: + if(ISCOMPLEX(p->vtype)) + { + ptype = cktype(OPCONV, p->vtype, ltype); + if(p->rightp) + ptype = cktype(OPCONV, ptype, rtype); + break; + } ptype = cktype(OPCONV, p->vtype, ltype); if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA) { *************** *** 1950,1955 return(TYADDR); case OPCONV: if(rt == 0) return(0); if(lt==TYCHAR && ISINT(rt) ) --- 1961,1972 ----- return(TYADDR); case OPCONV: + if(ISCOMPLEX(lt)) + { + if(ISNUMERIC(rt)) + return(lt); + ERR("impossible conversion") + } if(rt == 0) return(0); if(lt==TYCHAR && ISINT(rt) ) ---------------------------------------------------------------- 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