From 85f849ba0834b34dc196314c8db3d6801568c6a9 Mon Sep 17 00:00:00 2001 From: Zeex Date: Sat, 25 Apr 2015 13:26:46 +0600 Subject: [PATCH] Fix symbol nesting level not remembered for 2d+ arrays This fixes a bug where defining a 2d+ array variable in different blocks at the same nesting level would trigger a symbol redefinition error. For example: main() { new x; if (x) { new a[10][11]; } else { new a[10][12]; // error 021: symbol already defined: "a" } } It turned out that the compiler defines a separate symbol for each of the array dimensions but it only was setting sym->compound for the first of them, causing delete_symbols() to not delete the remaining dimension symbols. Now it sets the compound field for all dimensions. Fixes #60 --- source/compiler/sc.h | 2 +- source/compiler/sc1.c | 16 ++++++++-------- source/compiler/sc2.c | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/source/compiler/sc.h b/source/compiler/sc.h index caffea0..8187211 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -564,7 +564,7 @@ SC_FUNC symbol *finddepend(const symbol *parent); SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag, int usage); SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag, - int dim[],int numdim,int idxtag[]); + int dim[],int numdim,int idxtag[],int nestlevel); SC_FUNC int getlabel(void); SC_FUNC char *itoh(ucell val); diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 624e6ba..6447a89 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2092,7 +2092,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst } /* if */ litidx=0; if (sym==NULL) { /* define only if not yet defined */ - sym=addvariable(name,address,ident,sGLOBAL,tag,dim,numdim,idxtag); + sym=addvariable(name,address,ident,sGLOBAL,tag,dim,numdim,idxtag,nestlevel); if (sc_curstates>0) attachstatelist(sym,sc_curstates); } else { /* if declared but not yet defined, adjust the variable's address */ @@ -2210,11 +2210,11 @@ static int declloc(int fstatic) while (litidxcompound=nestlevel; /* for multiple declaration/shadowing check */ if (fconst) sym->usage|=uCONST; if (!fstatic) { /* static variables already initialized */ @@ -3455,7 +3454,7 @@ static void funcstub(int fnative) /* attach the array to the function symbol */ if (numdim>0) { assert(sym!=NULL); - sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag); + sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag,nestlevel); sub->parent=sym; } /* if */ @@ -4017,7 +4016,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, /* add details of type and address */ assert(numtags>0); argsym=addvariable(name,offset,ident,sLOCAL,tags[0], - arg->dim,arg->numdim,arg->idxtag); + arg->dim,arg->numdim,arg->idxtag,nestlevel); argsym->compound=0; if (ident==iREFERENCE) argsym->usage|=uREAD; /* because references are passed back */ @@ -5786,7 +5785,8 @@ static void doreturn(void) assert(curfunc->dim.arglist!=NULL); for (argcount=0; curfunc->dim.arglist[argcount].ident!=0; argcount++) /* nothing */; - sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL,curfunc->tag,dim,numdim,idxtag); + sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL, + curfunc->tag,dim,numdim,idxtag,nestlevel); sub->parent=curfunc; } /* if */ /* get the hidden parameter, copy the array (the array is on the heap; diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index d06b93d..8d60a05 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -2991,7 +2991,7 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i } SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag, - int dim[],int numdim,int idxtag[]) + int dim[],int numdim,int idxtag[],int nestlevel) { symbol *sym; @@ -3016,6 +3016,7 @@ SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int top->dim.array.level=(short)(numdim-level-1); top->x.tags.index=idxtag[level]; top->parent=parent; + top->compound=nestlevel; /* for multiple declaration/shadowing check */ parent=top; if (level==0) sym=top;