[4bsd-f77 #24] F77 sometimes breaks on concatenations
4.2 BSD f77 bug reports
4bsd-f77 at utah-cs.UUCP
Wed Aug 1 10:02:48 AEST 1984
From: Donn Seeley <donn at utah-cs.arpa>
Subject: F77 doesn't calculate the lengths of concatenations properly
Index: usr.bin/f77/src/f77pass1/put.c 4.2BSD
Description:
There are at least a couple errors in the f77 compiler in the
way it handles the lengths of concatenated strings. One of
them is a clear error in the code dealing with finding the
length of a concatenation of two CHARACTER variables; the other
is a failure to propagate the length of a CHARACTER variable
through parentheses. The first problem was found and fixed by
Conrad Huang at UC San Francisco.
Repeat-By:
I don't have a handy example of how the first problem breaks
some code, but the error is quite obvious from just looking at
the source.
The other bug can be shown by attempting to compile the
following program with the optimizer on:
----------------------------------------------------------------
program chcat
character*4 hi
character*6 there
character*1 excl
character*15 out
data hi/'hi'/
data there/'there'/
data excl/'!'/
out = (hi // there) // excl
print *, out
stop
end
----------------------------------------------------------------
The compiler bombs out with the following edifying messages:
----------------------------------------------------------------
chcat.f:
MAIN chcat:
Error on line 12 of chcat.f: nonarithmetic operand of arithmetic operator
Error on line 12 of chcat.f: impossible element in concatenation
Error. No assembly.
----------------------------------------------------------------
Fix:
The first bug is easy to identify and to fix. The problem is
that the code in lencat() implies that the 'varleng' field in
an 'Addrblock' stucture is at the same offset as the 'varleng'
field in a 'Tempblock' structure, which, alas, it is not. The
fix is in lencat(), in put.c:
----------------------------------------------------------------
*** /tmp/,RCSt1028292 Thu Jul 19 17:27:25 1984
--- put.c Thu Jul 19 12:04:26 1984
***************
*** 173,179
return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
return(p->headblock.vleng->constblock.const.ci);
! else if((p->tag==TADDR || p->tag==TTEMP) && p->addrblock.varleng!=0)
return(p->addrblock.varleng);
else
{
--- 186,192 -----
return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
return(p->headblock.vleng->constblock.const.ci);
! else if(p->tag==TADDR && p->addrblock.varleng!=0)
return(p->addrblock.varleng);
else if(p->tag==TTEMP && p->tempblock.varleng!=0)
return(p->tempblock.varleng);
***************
*** 175,180
return(p->headblock.vleng->constblock.const.ci);
else if((p->tag==TADDR || p->tag==TTEMP) && p->addrblock.varleng!=0)
return(p->addrblock.varleng);
else
{
err("impossible element in concatenation");
--- 188,195 -----
return(p->headblock.vleng->constblock.const.ci);
else if(p->tag==TADDR && p->addrblock.varleng!=0)
return(p->addrblock.varleng);
+ else if(p->tag==TTEMP && p->tempblock.varleng!=0)
+ return(p->tempblock.varleng);
else
{
err("impossible element in concatenation");
----------------------------------------------------------------
The second bug is due to the fact that for some obscure reason,
parentheses are treated as an operator in f77 (only when the
optimizer is enabled, by the way -- even so, none of the
optimization code appears to use the parenthesis operator for
anything). A parenthesis expression has the type of its
operand; unfortunately it does not propagate the length of its
operand when that operand is a CHARACTER expression, leading to
indirection through a null pointer (which explains the first
error message in the example) and a complaint from lencat()
because it can't get a length for one operand of a
concatenation operator (which explains the second error
message). Yet another bug is concealed behind this one, which
is that the intermediate code emitting routine putch1() does
not know what to do with a parenthesis expression anyway,
length or no length.
Here is the fix to fixexpr() in expr.c to force the length to
be passed through parentheses:
----------------------------------------------------------------
*** /tmp/,RCSt1028422 Thu Jul 19 17:48:21 1984
--- expr.c Thu Jul 19 17:21:27 1984
***************
*** 666,671
case OPCOMMA:
case OPQUEST:
case OPCOLON:
break;
case OPMIN:
--- 670,679 -----
case OPCOMMA:
case OPQUEST:
case OPCOLON:
+ break;
+
+ case OPPAREN:
+ p->vleng = cpexpr( lp->headblock.vleng );
break;
case OPMIN:
----------------------------------------------------------------
And here is the fix to putch1() in putpcc.c:
----------------------------------------------------------------
*** /tmp/,RCSt1028466 Thu Jul 19 17:54:01 1984
--- putpcc.c Thu Jul 19 17:23:05 1984
***************
*** 929,934
case OPCALL:
case OPCCALL:
t = putcall(p);
break;
case OPCONCAT:
--- 932,942 -----
case OPCALL:
case OPCCALL:
t = putcall(p);
+ break;
+
+ case OPPAREN:
+ --*ncommap;
+ t = putch1(p->exprblock.leftp, ncommap);
break;
case OPCONCAT:
----------------------------------------------------------------
Character manipulation in FORTRAN?!? -- You gotta be kidding,
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.bugs.4bsd.ucb-fixes
mailing list