diff --git a/source/compiler/sc.h b/source/compiler/sc.h index f60a1ad..48d43fd 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -549,6 +549,8 @@ long pc_lengthbin(void *handle); /* return the length of the file */ SC_FUNC void set_extension(char *filename,char *extension,int force); SC_FUNC symbol *fetchfunc(char *name,int tag); SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag); +SC_FUNC void check_tagmismatch(int formaltag,int actualtag,int allowcoerce,int errline); +SC_FUNC void check_tagmismatch_multiple(int formaltags[],int numtags,int actualtag,int errline); SC_FUNC char *funcdisplayname(char *dest,char *funcname); SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr); SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index); @@ -603,6 +605,7 @@ SC_FUNC char *itoh(ucell val); SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam, value *lval,int *resulttag); SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce); +SC_FUNC int checktag(int tags[],int numtags,int exprtag); SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult); SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state); SC_FUNC cell array_totalsize(symbol *sym); diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index b9260f2..ccd2c76 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -2352,8 +2352,7 @@ static int declloc(int fstatic) assert(staging); /* end staging phase (optimize expression) */ stgout(staging_start); stgset(FALSE); - if (!matchtag(tag,ctag,TRUE)) - error(213); /* tag mismatch */ + check_tagmismatch(tag,ctag,TRUE,-1); /* if the variable was not explicitly initialized, reset the * "uWRITTEN" flag that store() set */ if (!explicit_init) @@ -2508,8 +2507,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim, if (ident==iVARIABLE) { assert(*size==1); init(ident,&ctag,NULL); - if (!matchtag(tag,ctag,TRUE)) - error(213); /* tag mismatch */ + check_tagmismatch(tag,ctag,TRUE,-1); } else { assert(numdim>0); if (numdim==1) { @@ -2736,14 +2734,12 @@ static cell initvector(int ident,int tag,cell size,int startlit,int fillzero, rtag=symfield->x.tags.index; /* set the expected tag to the index tag */ enumfield=enumfield->next; } /* if */ - if (!matchtag(rtag,ctag,TRUE)) - error(213); /* tag mismatch */ + check_tagmismatch(rtag,ctag,TRUE,-1); } while (matchtoken(',')); /* do */ needtoken('}'); } else { init(ident,&ctag,errorfound); - if (!matchtag(tag,ctag,TRUE)) - error(213); /* tagname mismatch */ + check_tagmismatch(tag,ctag,TRUE,-1); } /* if */ /* fill up the literal queue with a series */ if (ellips) { @@ -2854,12 +2850,7 @@ static void decl_const(int vclass) needtoken('='); constexpr(&val,&exprtag,NULL); /* get value */ /* add_constant() checks for duplicate definitions */ - if (!matchtag(tag,exprtag,FALSE)) { - /* temporarily reset the line number to where the symbol was defined */ - errorset(sSETPOS,symbolline); - error(213); /* tagname mismatch */ - errorset(sSETPOS,-1); - } /* if */ + check_tagmismatch(tag,exprtag,FALSE,symbolline); sym=add_constant(constname,val,vclass,tag); if (sym!=NULL) sc_attachdocumentation(sym);/* attach any documenation to the constant */ @@ -3405,6 +3396,46 @@ static constvalue *find_tag_byval(int tag) return tagsym; } +SC_FUNC void check_tagmismatch(int formaltag,int actualtag,int allowcoerce,int errline) +{ + if (!matchtag(formaltag,actualtag,allowcoerce)) { + constvalue *tagsym; + char *formaltag_name,*actualtag_name; + tagsym=find_tag_byval(formaltag); + formaltag_name=(tagsym!=NULL) ? tagsym->name : "-unknown-"; + tagsym=find_tag_byval(actualtag); + actualtag_name=(tagsym!=NULL) ? tagsym->name : "-unknown-"; + if(errline>0) + errorset(sSETPOS,errline); + error(213,formaltag_name,actualtag_name); /* tag mismatch */ + if(errline>0) + errorset(sSETPOS,-1); + } /* if */ +} + +SC_FUNC void check_tagmismatch_multiple(int formaltags[],int numtags,int actualtag,int errline) +{ + if (!checktag(formaltags, numtags, actualtag)) { + int i; + constvalue *tagsym; + char formal_tagnames[sLINEMAX],*actual_tagname; + formal_tagnames[0]='\0'; + for (i=0; iname : "-unknown-",sizeof(formal_tagnames)); + if((i+1)!=numtags) + strlcat(formal_tagnames,"\" or \"",sizeof(formal_tagnames)); + } /* for */ + tagsym=find_tag_byval(actualtag); + actual_tagname=(tagsym!=NULL) ? tagsym->name : "-unknown-"; + if(errline>0) + errorset(sSETPOS,errline); + error(213,formal_tagnames,actual_tagname); /* tag mismatch */ + if(errline>0) + errorset(sSETPOS,-1); + } /* if */ +} + SC_FUNC char *funcdisplayname(char *dest,char *funcname) { int tags[2]; @@ -4112,8 +4143,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags, } else { constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL); assert(numtags>0); - if (!matchtag(tags[0],arg->defvalue_tag,TRUE)) - error(213); /* tagname mismatch */ + check_tagmismatch(tags[0],arg->defvalue_tag,TRUE,-1); } /* if */ } /* if */ } /* if */ @@ -6773,8 +6803,7 @@ static void doreturn(void) rettype|=uRETVALUE; /* function returns a value */ /* check tagname with function tagname */ assert(curfunc!=NULL); - if (!matchtag(curfunc->tag,tag,TRUE)) - error(213); /* tagname mismatch */ + check_tagmismatch(curfunc->tag,tag,TRUE,-1); if (ident==iARRAY || ident==iREFARRAY) { int dim[sDIMEN_MAX],numdim=0; cell arraysize; diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index 3421f46..235680e 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -293,6 +293,18 @@ SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce) return TRUE; } +SC_FUNC int checktag(int tags[],int numtags,int exprtag) +{ + int i; + + assert(tags!=0); + assert(numtags>0); + for (i=0; iident==iCONSTEXPR && lval2->ident==iCONSTEXPR) { /* only constant expression if both constant */ stgdel(index,cidx); /* scratch generated code and calculate */ - if (!matchtag(lval1->tag,lval2->tag,FALSE)) - error(213); /* tagname mismatch */ + check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult); } else { - if (!matchtag(lval1->tag,lval2->tag,FALSE)) - error(213); /* tagname mismatch */ + check_tagmismatch(lval1->tag,lval2->tag,FALSE,-1); (*oper)(); /* do the (signed) operation */ lval1->ident=iEXPRESSION; } /* if */ @@ -1044,8 +1054,8 @@ static int hier14(value *lval1) check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag); store(&lval3); /* now, store the expression result */ } /* if */ - if (!oper && !matchtag(lval3.tag,lval2.tag,TRUE)) - error(213); /* tagname mismatch (if "oper", warning already given in plunge2()) */ + if (!oper) + check_tagmismatch(lval3.tag,lval2.tag,TRUE,-1); /* tagname mismatch (if "oper", warning already given in plunge2()) */ if (lval3.sym) markusage(lval3.sym,uWRITTEN); pc_sideeffect=TRUE; @@ -1119,8 +1129,7 @@ static int hier13(value *lval) error(33,ptr); /* array must be indexed */ } /* if */ /* ??? if both are arrays, should check dimensions */ - if (!matchtag(lval->tag,lval2.tag,FALSE)) - error(213); /* tagname mismatch ('true' and 'false' expressions) */ + check_tagmismatch(lval->tag,lval2.tag,FALSE,-1); /* tagname mismatch ('true' and 'false' expressions) */ setlabel(flab2); if (sc_status==statFIRST) { /* Calculate the max. heap space used by either branch and save values of @@ -1604,8 +1613,7 @@ restart: if (lval2.ident==iARRAY || lval2.ident==iREFARRAY) error(33,lval2.sym->name); /* array must be indexed */ needtoken(close); - if (!matchtag(sym->x.tags.index,lval2.tag,TRUE)) - error(213); + check_tagmismatch(sym->x.tags.index,lval2.tag,TRUE,-1); if (lval2.ident==iCONSTEXPR) { /* constant expression */ stgdel(index,cidx); /* scratch generated code */ if (lval1->arrayidx!=NULL) { /* keep constant index, for checking */ @@ -1948,18 +1956,6 @@ static int findnamedarg(arginfo *arg,char *name) return -1; } -static int checktag(int tags[],int numtags,int exprtag) -{ - int i; - - assert(tags!=0); - assert(numtags>0); - for (i=0; i0); check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag); - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag)) - error(213); + check_tagmismatch_multiple(arg[argidx].tags,arg[argidx].numtags,lval.tag,-1); if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); argidx++; /* argument done */ @@ -2192,8 +2186,7 @@ static int nesting=0; } /* if */ } /* if */ /* otherwise, the address is already in PRI */ - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag)) - error(213); + check_tagmismatch_multiple(arg[argidx].tags,arg[argidx].numtags,lval.tag,-1); if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); argidx++; /* argument done */ @@ -2269,8 +2262,7 @@ static int nesting=0; append_constval(&arrayszlst,arg[argidx].name,sym->dim.array.length,level); } /* if */ /* address already in PRI */ - if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag)) - error(213); + check_tagmismatch_multiple(arg[argidx].tags,arg[argidx].numtags,lval.tag,-1); if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); // ??? set uWRITTEN? @@ -2545,8 +2537,8 @@ static int constant(value *lval) error(8); /* must be constant expression */ if (lasttag<0) lasttag=tag; - else if (!matchtag(lasttag,tag,FALSE)) - error(213); /* tagname mismatch */ + else + check_tagmismatch(lasttag,tag,FALSE,-1); litadd(item); /* store expression result in literal table */ } while (matchtoken(',')); if (!needtoken('}')) diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index ac08c96..9c83d76 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -167,7 +167,7 @@ static char *warnmsg[] = { /*210*/ "possible use of symbol before initialization: \"%s\"\n", /*211*/ "possibly unintended assignment\n", /*212*/ "possibly unintended bitwise operation\n", -/*213*/ "tag mismatch\n", +/*213*/ "tag mismatch: expected tag(s) \"%s\", but found \"%s\"\n", /*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n", /*215*/ "expression has no effect\n", /*216*/ "nested comment\n",