Subject: sprintf() returning 'int' breaks f77 (#247) Index: usr.bin/f77/driver.c,pdp11.c 2.11BSD Description: Update #233 changed the return value of sprintf() from "char *" (a copy of the first parameter) to 'int' (the number of characters placed in the buffer). This change breaks applications which relied on the return value of sprintf() being a buffer address. f77 is one of those applications. Repeat-By: Compile a Fortran program. Since a 'int' is being passed instead of a string in a number of places the result is either a stream of errors or a core dump. Fix: Thanks to Tom (tih@nhh.no) for spotting this and providing the initial fix. The 'Makefile' was updated slightly to take advantage of the ability to pipe into the assembler ('as'). This speeds things up somewhat by removing a 'mv' and creation of another intermediate file. Apply the patch below, recompile and install f77: 1) Cut where indicated and save to a file, /tmp/247 2) patch -p0 < /tmp/247 3) cd /usr/src/usr.bin/f77 4) make make install make clean ===========================cut here========================== *** /usr/src/usr.bin/f77/Makefile.old Mon Jan 18 09:36:47 1993 --- /usr/src/usr.bin/f77/Makefile Fri Jun 9 21:33:01 1995 *************** *** 2,8 **** # generating code for the PDP11, # using the Ritchie pass 2 # ! # 3/8/85 WEB # AS= as -V --- 2,8 ---- # generating code for the PDP11, # using the Ritchie pass 2 # ! # 1995/06/09 - 2.11BSD # AS= as -V *************** *** 73,86 **** # Remove error strings mkstr - f77_strings xx $*.c ${CC} -S ${CFLAGS} xx$*.c - mv xx$*.s $*.s # Move switch code to text space ! -if [ X${SEPFLAG} = X-n ]; then ed - $*.s < :rofix; fi ! rm xx$*.c ! ${C2} $*.s x.s ! mv x.s $*.s ! ${AS} - -o $*.o $*.s ! rm $*.s driver.o: pdp11x.o: --- 73,82 ---- # Remove error strings mkstr - f77_strings xx $*.c ${CC} -S ${CFLAGS} xx$*.c # Move switch code to text space ! -if [ X${SEPFLAG} = X-n ]; then ed - xx$*.s < :rofix; fi ! ${C2} xx$*.s | ${AS} -u -o $*.o ! rm xx$*.c xx$*.s driver.o: pdp11x.o: *** /usr/src/usr.bin/f77/driver.c.old Sun Jun 12 16:24:58 1988 --- /usr/src/usr.bin/f77/driver.c Fri Jun 9 21:07:06 1995 *************** *** 1,4 **** ! char *xxxvers[] = "\n FORTRAN 77 DRIVER, VERSION 1.13+, 24 SEP 1982\n"; #include #include --- 1,4 ---- ! char *xxxvers[] = "\n FORTRAN 77 DRIVER, VERSION 1.13.1+, 09 JUN 1995\n"; #include #include *************** *** 268,274 **** if(macroflag) { ! if(sys(sprintf(buff, "%s %s >%s", macroname, infname, prepfname) )) { rmf(prepfname); erred = YES; --- 268,275 ---- if(macroflag) { ! sprintf(buff, "%s %s >%s", macroname, infname, prepfname); ! if (sys(buff)) { rmf(prepfname); erred = YES; *************** *** 442,451 **** #ifdef PASS2OPT if(optimflag) { ! if( sys(sprintf(buff, "%s %s %s", PASS2OPT, asmpass2, optzfname)) ) rmf(optzfname); else ! sys(sprintf(buff,"mv %s %s", optzfname, asmpass2)); } #endif #endif --- 443,456 ---- #ifdef PASS2OPT if(optimflag) { ! sprintf(buff, "%s %s %s", PASS2OPT, asmpass2, optzfname); ! if (sys(buff)) rmf(optzfname); else ! { ! sprintf(buff,"mv %s %s", optzfname, asmpass2); ! sys(buff); ! } } #endif #endif *************** *** 454,464 **** { *lastc = 's'; #if TARGET == INTERDATA ! sys( sprintf(buff, "cat %s %s %s >%s", ! asmfname, setfname, asmpass2, obj) ); #else ! sys( sprintf(buff, "cat %s %s >%s", ! asmfname, asmpass2, obj) ); #endif *lastc = 'o'; } --- 459,469 ---- { *lastc = 's'; #if TARGET == INTERDATA ! sprintf(buff, "cat %s %s %s >%s", asmfname, setfname, asmpass2, obj); ! sys(buff); #else ! sprintf(buff, "cat %s %s >%s", asmfname, asmpass2, obj); ! sys(buff); #endif *lastc = 'o'; } *************** *** 472,478 **** #if TARGET == VAX /* vax assembler currently accepts only one input file */ ! sys(sprintf(buff, "cat %s >>%s", asmpass2, asmfname)); sprintf(buff, "%s -o %s %s", asmname, obj, asmfname); #endif --- 477,484 ---- #if TARGET == VAX /* vax assembler currently accepts only one input file */ ! sprintf(buff, "cat %s >>%s", asmpass2, asmfname); ! sys(buff); sprintf(buff, "%s -o %s %s", asmname, obj, asmfname); #endif *************** *** 536,544 **** #if HERE==INTERDATA if(optimflag) { ! char buff[100]; ! if( sys(sprintf(buff, "nopt %s -o junk.%d", aoutname, pid)) ! || sys(sprintf(buff, "mv junk.%d %s", pid, aoutname)) ) err("bad optimization"); } #endif --- 542,551 ---- #if HERE==INTERDATA if(optimflag) { ! char bufa[100], bufb[100]; ! sprintf(bufa, "nopt %s -o junk.%d", aoutname, pid); ! sprintf(bufb, "mv junk.%d %s", pid, aoutname); ! if (sys(bufa) || sys(bufb)) err("bad optimization"); } #endif *************** *** 961,967 **** char *t, *d; { char buff[100]; ! fatal( sprintf(buff, t, d) ); } --- 968,975 ---- char *t, *d; { char buff[100]; ! sprintf(buff, t, d); ! fatal(buff); } *************** *** 1006,1012 **** totlen = 0; nch = 0; ! if(status = sys( sprintf(buff, "sort %s >%s", initfname, sortfname) ) ) fatal1("call sort status = %d", status); if( (sortfile = fopen(sortfname, "r")) == NULL) badfile(sortfname); --- 1014,1021 ---- totlen = 0; nch = 0; ! sprintf(buff, "sort %s >%s", initfname, sortfname); ! if (status = sys(buff)) fatal1("call sort status = %d", status); if( (sortfile = fopen(sortfname, "r")) == NULL) badfile(sortfname); *** /usr/src/usr.bin/f77/pdp11.c.old Sun Jun 12 16:24:58 1988 --- /usr/src/usr.bin/f77/pdp11.c Fri Jun 9 20:34:02 1995 *************** *** 1,3 **** --- 1,8 ---- + /* + * 1995/06/09. sprintf() returns an int (since patch #233) rather + * a "char *". + */ + #include "defs" #include "string_defs" #if FAMILY == DMR *************** *** 29,35 **** p2op(P2RETURN); #endif #if FAMILY==SCJ ! p2pass(sprintf(textline, "\tjmp\tcret")); #endif } --- 34,41 ---- p2op(P2RETURN); #endif #if FAMILY==SCJ ! sprintf(textline, "\tjmp\tcret"); ! p2pass(textline); #endif } *************** *** 70,76 **** putstmt(); #endif #if FAMILY == SCJ ! p2pass(sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n)); #endif } --- 76,83 ---- putstmt(); #endif #if FAMILY == SCJ ! sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n); ! p2pass(textline); #endif } *************** *** 154,169 **** if(p->vtype == TYLONG) { regno = 1; ! p2pass(sprintf(textline, "\ttst\tr0")); ! p2pass(sprintf(textline, "\tbne\tL%d", skiplabel)); } else regno = 0; ! p2pass(sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab)); ! p2pass(sprintf(textline, "\tbhi\tL%d", skiplabel)); ! p2pass(sprintf(textline, "\tasl\tr%d", regno)); ! p2pass(sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno)); } --- 161,182 ---- if(p->vtype == TYLONG) { regno = 1; ! sprintf(textline, "\ttst\tr0"); ! p2pass(textline); ! sprintf(textline, "\tbne\tL%d", skiplabel); ! p2pass(textline); } else regno = 0; ! sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab); ! p2pass(textline); ! sprintf(textline, "\tbhi\tL%d", skiplabel); ! p2pass(textline); ! sprintf(textline, "\tasl\tr%d", regno); ! p2pass(textline); ! sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno); ! p2pass(textline); } *************** *** 176,198 **** putforce( ptype = p->vtype, p); if( ISINT(ptype) ) { ! p2pass(sprintf(textline, "\ttst\tr0")); ! p2pass(sprintf(textline, "\tjlt\tL%d", neg)); ! p2pass(sprintf(textline, "\tjgt\tL%d", pos)); if(ptype != TYSHORT) { ! p2pass(sprintf(textline, "\ttst\tr1")); ! p2pass(sprintf(textline, "\tjeq\tL%d", zer)); } ! p2pass(sprintf(textline, "\tjbr\tL%d", pos)); } else { ! p2pass(sprintf(textline, "\ttstf\tr0")); ! p2pass(sprintf(textline, "\tcfcc")); ! p2pass(sprintf(textline, "\tjeq\tL%d", zer)); ! p2pass(sprintf(textline, "\tjlt\tL%d", neg)); ! p2pass(sprintf(textline, "\tjmp\tL%d", pos)); } } --- 189,222 ---- putforce( ptype = p->vtype, p); if( ISINT(ptype) ) { ! sprintf(textline, "\ttst\tr0"); ! p2pass(textline); ! sprintf(textline, "\tjlt\tL%d", neg); ! p2pass(textline); ! sprintf(textline, "\tjgt\tL%d", pos); ! p2pass(textline); if(ptype != TYSHORT) { ! sprintf(textline, "\ttst\tr1"); ! p2pass(textline); ! sprintf(textline, "\tjeq\tL%d", zer); ! p2pass(textline); } ! sprintf(textline, "\tjbr\tL%d", pos); ! p2pass(textline); } else { ! sprintf(textline, "\ttstf\tr0"); ! p2pass(textline); ! sprintf(textline, "\tcfcc"); ! p2pass(textline); ! sprintf(textline, "\tjeq\tL%d", zer); ! p2pass(textline); ! sprintf(textline, "\tjlt\tL%d", neg); ! p2pass(textline); ! sprintf(textline, "\tjmp\tL%d", pos); ! p2pass(textline); } } *************** *** 265,271 **** prtail() { #if FAMILY == SCJ ! p2pass(sprintf(textline, "\t.globl\tcsv,cret")); #else p2op(P2EOF); #endif --- 289,296 ---- prtail() { #if FAMILY == SCJ ! sprintf(textline, "\t.globl\tcsv,cret"); ! p2pass(textline); #else p2op(P2EOF); #endif *************** *** 299,312 **** if(profileflag) proflab = newlabel(); #if FAMILY == SCJ ! p2pass(sprintf(textline, "\tjsr\tr5,csv")); if(profileflag) { fprintf(asmfile, ".data\nL%d:\t_%s+1\n.bss\n", proflab, funcname); ! p2pass(sprintf(textline, "\tmov\t$L%d,r0", proflab)); ! p2pass(sprintf(textline, "\tjsr\tpc,mcount")); } ! p2pass(sprintf(textline, "\tsub\t$.F%d,sp", procno)); #else p2op(P2SAVE); if(profileflag) { --- 324,341 ---- if(profileflag) proflab = newlabel(); #if FAMILY == SCJ ! sprintf(textline, "\tjsr\tr5,csv"); ! p2pass(textline); if(profileflag) { fprintf(asmfile, ".data\nL%d:\t_%s+1\n.bss\n", proflab, funcname); ! sprintf(textline, "\tmov\t$L%d,r0", proflab); ! p2pass(textline); ! sprintf(textline, "\tjsr\tpc,mcount"); ! p2pass(textline); } ! sprintf(textline, "\tsub\t$.F%d,sp", procno); ! p2pass(textline); #else p2op(P2SAVE); if(profileflag) { *************** *** 376,382 **** char *s; { #if FAMILY == SCJ ! p2pass(sprintf(textline, "_%s:", s)); #else p2op(P2RLABEL); putc('_', textfile); --- 405,412 ---- char *s; { #if FAMILY == SCJ ! sprintf(textline, "_%s:", s); ! p2pass(textline); #else p2op(P2RLABEL); putc('_', textfile); *************** *** 391,398 **** int k; { #if FAMILY == SCJ ! p2pass(sprintf(textline, "\tmov\tr5,r4")); ! p2pass(sprintf(textline, "\tadd\t$%d.,r4", k)); #else p2reg(ARGREG, P2SHORT); p2reg(AUTOREG, P2SHORT); --- 421,430 ---- int k; { #if FAMILY == SCJ ! sprintf(textline, "\tmov\tr5,r4"); ! p2pass(textline); ! sprintf(textline, "\tadd\t$%d.,r4", k); ! p2pass(textline); #else p2reg(ARGREG, P2SHORT); p2reg(AUTOREG, P2SHORT); *************** *** 449,457 **** for(hp = hashtab ; hpvarp) { ! s = NULL; if(p->vstg == STGARG) ! s = sprintf(buff, "%o", p->vardesc.varno+argloc); else if(p->vclass == CLVAR) switch(p->vstg) { --- 481,489 ---- for(hp = hashtab ; hpvarp) { ! buff[0] = '\0'; if(p->vstg == STGARG) ! sprintf(buff, "%o", p->vardesc.varno+argloc); else if(p->vclass == CLVAR) switch(p->vstg) { *************** *** 460,479 **** case STGEQUIV: t = memname(p->vstg, p->vardesc.varno); if(p->voffset) ! s = sprintf(buff, "%s+%o", t, p->voffset); else ! s = sprintf(buff, "%s", t); break; case STGAUTO: ! s = sprintf(buff, "%o", p->voffset); break; default: break; } ! if(s) ! fprintf(asmfile, "~%s = %s\n", varstr(VL,p->varname), s); } fprintf(asmfile, "~~:\n"); } --- 492,511 ---- case STGEQUIV: t = memname(p->vstg, p->vardesc.varno); if(p->voffset) ! sprintf(buff, "%s+%o", t, p->voffset); else ! sprintf(buff, "%s", t); break; case STGAUTO: ! sprintf(buff, "%o", p->voffset); break; default: break; } ! if (buff[0]) ! fprintf(asmfile, "~%s = %s\n", varstr(VL,p->varname), buff); } fprintf(asmfile, "~~:\n"); } *** /VERSION.old Sat May 20 21:04:31 1995 --- /VERSION Fri Jun 9 20:57:38 1995 *************** *** 1,4 **** ! Current Patch Level: 246 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 247 2.11 BSD ============