ljp@sm.luth.se (Johan Persson) (11/06/90)
When I tried to compile a program, (which had compiled nice on a SUN workstation with both gcc and cc) on one of our old VAX 11/750 I got the fantastic error .. line 2706 compiler error: schain botch (4.3 BSD and cc) Does anyone have any clue to what that means ? --- Internet: ljp@sm.luth.se Johan Persson BITNET: ljp%sm.luth.se@sekth.bitnet Dept of Math & CS ARPA: ljp%sm.luth.se@ucbvax.berkely.ed U of Lule}
chris@mimsy.umd.edu (Chris Torek) (11/07/90)
In article <627@my.sm.luth.se> ljp@sm.luth.se (Johan Persson) writes: > .. line 2706 compiler error: schain botch (4.3 BSD and cc) You have the version of the C compiler that I sped up by 15% and in the process inserted a bug. An `schain botch' occurs when a scope chain gets messed up, which happens when the symbol table is moderately full, two symbols hash to the same position, and the one that is inserted second goes at a lower scope than the one that is inserted first (i.e., is a `goto' label or an `extern' definition). You might try the following patch. It fixes a number of bugs and adds one function that your grammar will not be using. (Note, the pathname in 4.3BSD was /usr/src/lib/mip/pftn.c.) RCS file: /usr/src/libexec/pcc/mip/RCS/pftn.c,v revision 1.7 date: 90/06/18 03:28:44; author: chris; state: Exp; lines added/del: 3/2 ucb 1.28: mckusick: generate a semantic message instead of dying (4.3BSD-tahoe/libexec/2) ---------------------------- revision 1.6 date: 89/10/14 02:37:55; author: chris; state: Exp; lines added/del: 0/5 try this fix for enum redeclaration instead ---------------------------- revision 1.5 date: 89/05/01 17:36:29; author: chris; state: Exp; lines added/del: 0/1 back out change in 1.3; using Donn's change instead ---------------------------- revision 1.4 date: 88/10/20 09:01:53; author: chris; state: Exp; lines added/del: 3/2 fix enum redeclaration bug: the sequence enum {a=1}; f() { enum{a=1}; would leave the inner `a' value 2, not 1. ---------------------------- revision 1.3 date: 88/03/23 09:11:36; author: chris; state: Exp; lines added/del: 1/0 no complaints about empty arrays for each `char c[] = "str"' construct after errors, please ---------------------------- revision 1.2 date: 88/03/20 22:01:16; author: chris; state: Exp; lines added/del: 80/39 from okeeffe via trantor: mostly Donn Seeley's work ---------------------------- revision 1.1 date: 88/03/20 21:56:50; author: chris; state: Exp; Initial revision ============================================================================= RCS file: RCS/pftn.c,v retrieving revision 1.1 diff -c2 -r1.1 pftn.c *** /tmp/,RCSt1003312 Tue Nov 6 15:40:42 1990 --- pftn.c Mon Jun 18 03:28:46 1990 *************** *** 1,4 **** #ifndef lint ! static char *sccsid ="@(#)pftn.c 1.12 (Berkeley) 4/21/86"; #endif lint --- 1,4 ---- #ifndef lint ! static char *sccsid ="@(#)pftn.c 1.28 (Berkeley) 4/30/90"; #endif lint *************** *** 85,91 **** if( stp == FTN && p->sclass == SNULL )goto enter; ! /* name encountered as function, not yet defined */ ! if( stp == UNDEF|| stp == FARG ){ ! if( blevel==1 && stp!=FARG ) switch( class ){ default: --- 85,89 ---- if( stp == FTN && p->sclass == SNULL )goto enter; ! if( blevel==1 && stp!=FARG ) switch( class ){ default: *************** *** 104,111 **** ; } ! goto enter; ! } if( type != stp ) goto mismatch; /* test (and possibly adjust) dimensions */ dsym = p->dimoff; --- 102,112 ---- ; } ! if( stp == UNDEF|| stp == FARG ) goto enter; if( type != stp ) goto mismatch; + if( blevel > slev && (class == AUTO || class == REGISTER) ) + /* new scope */ + goto mismatch; + /* test (and possibly adjust) dimensions */ dsym = p->dimoff; *************** *** 217,224 **** case MOE: - if( scl == class ){ - if( p->offset!= strucoff++ ) break; - psave( idp ); - } break; --- 218,221 ---- *************** *** 258,266 **** && stab[*memp].sclass != UNAME; /* iterate */ --memp){ char *cname, *oname; ! if( stab[*memp].sflags & SNONUNIQ ){int k; cname=p->sname; oname=stab[*memp].sname; #ifndef FLEXNAMES ! for(k=1; k<=NCHNAM; ++k){ if(*cname++ != *oname)goto diff; if(!*oname++)break; --- 255,263 ---- && stab[*memp].sclass != UNAME; /* iterate */ --memp){ char *cname, *oname; ! if( stab[*memp].sflags & SNONUNIQ ){ cname=p->sname; oname=stab[*memp].sname; #ifndef FLEXNAMES ! for(temp=1; temp<=NCHNAM; ++temp){ if(*cname++ != *oname)goto diff; if(!*oname++)break; *************** *** 327,331 **** /* allocate offsets */ if( class&FIELD ){ ! falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */ psave( idp ); } --- 324,328 ---- /* allocate offsets */ if( class&FIELD ){ ! (void) falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */ psave( idp ); } *************** *** 333,337 **** case AUTO: ! oalloc( p, &autooff ); break; case STATIC: --- 330,334 ---- case AUTO: ! (void) oalloc( p, &autooff ); break; case STATIC: *************** *** 345,349 **** p->slevel = 2; if( class == LABEL ){ ! locctr( PROG ); deflab( p->offset ); } --- 342,346 ---- p->slevel = 2; if( class == LABEL ){ ! (void) locctr( PROG ); deflab( p->offset ); } *************** *** 358,362 **** case MOU: case MOS: ! oalloc( p, &strucoff ); if( class == MOU ) strucoff = 0; psave( idp ); --- 355,359 ---- case MOU: case MOS: ! (void) oalloc( p, &strucoff ); if( class == MOU ) strucoff = 0; psave( idp ); *************** *** 404,408 **** ftnend(){ /* end of function */ ! if( retlab != NOLAB ){ /* inside a real function */ efcode(); } --- 401,405 ---- ftnend(){ /* end of function */ ! if( retlab != NOLAB && nerrors == 0 ){ /* inside a real function */ efcode(); } *************** *** 425,429 **** swx = 0; swp = swtab; ! locctr(DATA); } --- 422,426 ---- swx = 0; swp = swtab; ! (void) locctr(DATA); } *************** *** 455,459 **** } cendarg(); ! locctr(PROG); defalign(ALINT); ftnno = getlab(); --- 452,456 ---- } cendarg(); ! (void) locctr(PROG); defalign(ALINT); ftnno = getlab(); *************** *** 540,546 **** register high, low; ! /* paramstack contains: ! paramstack[ oparam ] = previous instruct ! paramstack[ oparam+1 ] = previous class paramstk[ oparam+2 ] = previous strucoff paramstk[ oparam+3 ] = structure name --- 537,543 ---- register high, low; ! /* paramstk contains: ! paramstk[ oparam ] = previous instruct ! paramstk[ oparam+1 ] = previous class paramstk[ oparam+2 ] = previous strucoff paramstk[ oparam+3 ] = structure name *************** *** 706,710 **** case FTN: ! cerror( "compiler takes alignment of function"); case PTR: return( ALPOINT ); --- 703,708 ---- case FTN: ! uerror( "can't assign to function" ); ! return( ALCHAR ); case PTR: return( ALPOINT ); *************** *** 755,759 **** case FTN: ! cerror( "compiler takes size of function"); case PTR: return( SZPOINT * mult ); --- 753,759 ---- case FTN: ! /* cerror( "compiler takes size of function"); */ ! uerror( "can't take size of function" ); ! return( SZCHAR ); case PTR: return( SZPOINT * mult ); *************** *** 859,865 **** case STATIC: ilocctr = ISARY(p->stype)?ADATA:DATA; ! locctr( ilocctr ); ! defalign( talign( p->stype, p->sizoff ) ); ! defnam( p ); } --- 859,867 ---- case STATIC: ilocctr = ISARY(p->stype)?ADATA:DATA; ! if( nerrors == 0 ){ ! (void) locctr( ilocctr ); ! defalign( talign( p->stype, p->sizoff ) ); ! defnam( p ); ! } } *************** *** 966,970 **** strflg = 0; lxstr(0); /* get the contents */ ! locctr( blevel==0?ilocctr:temp ); p = buildtree( STRING, NIL, NIL ); p->tn.rval = -l; --- 968,972 ---- strflg = 0; lxstr(0); /* get the contents */ ! (void) locctr( blevel==0?ilocctr:temp ); p = buildtree( STRING, NIL, NIL ); p->tn.rval = -l; *************** *** 1036,1039 **** --- 1038,1051 ---- } + fixinit(){ + /* called from the grammar if we must punt during initialization */ + /* stolen from endinit() */ + pstk = instack; + paramno = 0; + vfdalign( AL_INIT ); + inoff = 0; + iclass = SNULL; + } + doinit( p ) register NODE *p; { *************** *** 1094,1097 **** --- 1106,1113 ---- p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); + #ifdef LINT + /* force lint to treat this like an assignment */ + ecode(p); + #endif p->in.left->in.op = FREE; p->in.left = p->in.right; *************** *** 1106,1110 **** if( sz < SZINT ){ /* special case: bit fields, etc. */ ! if( o != ICON ) uerror( "illegal initialization" ); else incode( p->in.left, sz ); } --- 1122,1127 ---- if( sz < SZINT ){ /* special case: bit fields, etc. */ ! if( o != ICON || p->in.left->tn.rval != NONAME ) ! uerror( "illegal initialization" ); else incode( p->in.left, sz ); } *************** *** 1380,1384 **** } #ifdef LCOMM ! /* hack so stab will come at as LCSYM rather than STSYM */ if (class == STATIC) { extern int stabLCSYM; --- 1397,1401 ---- } #ifdef LCOMM ! /* hack so stab will come out as LCSYM rather than STSYM */ if (class == STATIC) { extern int stabLCSYM; *************** *** 1389,1392 **** --- 1406,1414 ---- defid( p, class ); + /* if an array is not initialized, no empty dimension */ + if( class!=EXTERN && class!=TYPEDEF && + ISARY(p->in.type) && dimtab[p->fn.cdim]==0 ) + uerror("null storage definition"); + #ifndef LCOMM if( class==EXTDEF || class==STATIC ) *************** *** 1527,1532 **** temp = p->in.right->tn.lval; p->in.right->in.op = FREE; ! if( ( temp == 0 ) & ( p->in.left->tn.op == LB ) ) ! uerror( "Null dimension" ); } --- 1549,1554 ---- temp = p->in.right->tn.lval; p->in.right->in.op = FREE; ! if( temp == 0 && p->in.left->tn.op == LB ) ! uerror( "null dimension" ); } *************** *** 1563,1573 **** /* detect function arguments, watching out for structure declarations */ ! /* for example, beware of f(x) struct [ int a[10]; } *x; { ... } */ /* the danger is that "a" will be converted to a pointer */ ! if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) class = PARAM; if( class == PARAM || ( class==REGISTER && blevel==1 ) ){ if( type == FLOAT ) type = DOUBLE; else if( ISARY(type) ){ ++p->fn.cdim; type += (PTR-ARY); --- 1585,1601 ---- /* detect function arguments, watching out for structure declarations */ ! /* for example, beware of f(x) struct { int a[10]; } *x; { ... } */ /* the danger is that "a" will be converted to a pointer */ ! if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) ! class = PARAM; if( class == PARAM || ( class==REGISTER && blevel==1 ) ){ if( type == FLOAT ) type = DOUBLE; else if( ISARY(type) ){ + #ifdef LINT + if( hflag && dimtab[p->fn.cdim]!=0 ) + werror("array[%d] type changed to pointer", + dimtab[p->fn.cdim]); + #endif ++p->fn.cdim; type += (PTR-ARY); *************** *** 1701,1705 **** register i; register struct symtab * sp; ! char *p,*q; sp = & stab[ i= *idindex ]; /* position search at old entry */ --- 1729,1733 ---- register i; register struct symtab * sp; ! char *q; sp = & stab[ i= *idindex ]; /* position search at old entry */ *************** *** 1713,1717 **** } sp->sflags = SNONUNIQ | SMOS; - p = sp->sname; q = stab[*idindex].sname; /* old entry name */ #ifdef FLEXNAMES --- 1741,1744 ---- *************** *** 1726,1731 **** *idindex = i; #ifndef FLEXNAMES ! for( i=1; i<=NCHNAM; ++i ){ /* copy name */ ! if( *p++ = *q /* assign */ ) ++q; } #endif --- 1753,1760 ---- *idindex = i; #ifndef FLEXNAMES ! { ! char *p = sp->sname; ! for( i=1; i<=NCHNAM; ++i ) /* copy name */ ! if( *p++ = *q /* assign */ ) ++q; } #endif *************** *** 1737,1741 **** register char *p, *q; ! int i, j, ii; register struct symtab *sp; --- 1766,1773 ---- register char *p, *q; ! int i, ii; ! #ifndef FLEXNAMES ! int j; ! #endif register struct symtab *sp; *************** *** 1854,1859 **** /* step 1: remove entries */ while( chaintop-1 > lev ){ - register int type; - p = schain[--chaintop]; schain[chaintop] = 0; --- 1886,1889 ---- *************** *** 1860,1864 **** for( ; p; p = q ){ q = p->snext; - type = p->stype; if( p->stype == TNULL || p->slevel <= lev ) cerror( "schain botch" ); --- 1890,1893 ---- *************** *** 1894,1898 **** p = clist; while( p ){ ! register struct symtab *r, *next; q = p; --- 1923,1927 ---- p = clist; while( p ){ ! register struct symtab *next, **t, *r; q = p; *************** *** 1902,1905 **** --- 1931,1942 ---- if( q == p || q->stype == TNULL )break; if( (r = relook(q)) != q ) { + /* move q in schain list */ + t = &schain[q->slevel]; + while( *t && *t != q ) + t = &(*t)->snext; + if( *t ) + *t = r; + else + cerror("schain botch 2"); *r = *q; q->stype = TNULL; *************** *** 1936,1940 **** unhide( p ) register struct symtab *p; { register struct symtab *q; ! register s, j; s = p->sflags & (SMOS|STAG); --- 1973,1977 ---- unhide( p ) register struct symtab *p; { register struct symtab *q; ! register s; s = p->sflags & (SMOS|STAG); *************** *** 1950,1953 **** --- 1987,1991 ---- if( (q->sflags&(SMOS|STAG)) == s ){ #ifndef FLEXNAMES + register j; for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break; if( j == NCHNAM ){ /* found the name */ -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
avery@netcom.UUCP (Avery Colter) (11/11/90)
cc: "So, Moishe, didn't listen to your poor mama about proper coding, ya had to code this schaine botch right in there? Veh ist mir...." -- Avery Ray Colter {apple|claris}!netcom!avery {decwrl|mips|sgi}!btr!elfcat (415) 839-4567 "Fat and steel: two mortal enemies locked in deadly combat." - "The Bending of the Bars", A. R. Colter