[comp.lang.c] SCHAIN BOTCH ????

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