Bug fixes.

This commit is contained in:
David Anderson 2014-07-03 00:14:12 -07:00
parent 86cd906371
commit ed4cca0225
5 changed files with 31 additions and 13 deletions

View File

@ -515,8 +515,9 @@ typedef enum s_optmark {
#define FUNCTAG 0x20000000Lu
#define OBJECTTAG 0x10000000Lu
#define ENUMTAG 0x08000000Lu
#define METHODMAPTAG 0x04000000Lu
#define TAGMASK (~PUBLICTAG)
#define TAGTYPEMASK (FUNCTAG | OBJECTTAG | ENUMTAG)
#define TAGTYPEMASK (FUNCTAG | OBJECTTAG | ENUMTAG | METHODMAPTAG)
#define TAGFLAGMASK (FIXEDTAG | TAGTYPEMASK)
#define CELL_MAX (((ucell)1 << (sizeof(cell)*8-1)) - 1)
@ -915,6 +916,7 @@ SC_VDECL int pc_functag; /* global function tag */
SC_VDECL int pc_tag_string; /* global String tag */
SC_VDECL int pc_tag_void; /* global void tag */
SC_VDECL int pc_tag_object; /* root object tag */
SC_VDECL int pc_tag_bool; /* global bool tag */
SC_VDECL int pc_anytag; /* global any tag */
SC_VDECL int glbstringread; /* last global string read */
SC_VDECL int sc_require_newdecls; /* only newdecls are allowed */

View File

@ -78,6 +78,7 @@ int pc_functag = 0;
int pc_tag_string = 0;
int pc_tag_void = 0;
int pc_tag_object = 0;
int pc_tag_bool = 0;
typedef struct funcstub_setup_s {
const char *name;
@ -1346,6 +1347,7 @@ static void setconstants(void)
sc_rationaltag = pc_addtag("Float");
pc_tag_void = pc_addtag_flags("void", FIXEDTAG);
pc_tag_object = pc_addtag_flags("object", FIXEDTAG|OBJECTTAG);
pc_tag_bool = pc_addtag("bool");
add_constant("true",1,sGLOBAL,1); /* boolean flags */
add_constant("false",0,sGLOBAL,1);
@ -3292,9 +3294,15 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
case tOBJECT:
type->tag = pc_tag_object;
break;
case tLABEL:
type->tag = pc_addtag(tok.str);
error(120);
break;
case tSYMBOL:
if (strcmp(tok.str, "float") == 0) {
type->tag = sc_rationaltag;
} else if (strcmp(tok.str, "bool") == 0) {
type->tag == pc_tag_bool;
} else {
type->tag = pc_findtag(tok.str);
if (type->tag == sc_rationaltag) {
@ -4018,7 +4026,7 @@ static void domethodmap(LayoutSpec spec)
map->spec = spec;
strcpy(map->name, mapname);
if (spec == Layout_MethodMap) {
map->tag = pc_addtag(mapname);
map->tag = pc_addtag_flags(mapname, FIXEDTAG | METHODMAPTAG);
} else {
constvalue *tagptr = pc_tagptr(mapname);
if (!tagptr) {
@ -4626,6 +4634,15 @@ static void attachstatelist(symbol *sym, int state_id)
} /* if */
}
// This simpler version of matchtag() only checks whether two tags represent
// the same type. Because methodmaps are attached to types and are not actually
// types themselves, we strip out the methodmap bit in case a methodmap was
// seen later than another instance of a tag.
static int compare_tag(int tag1, int tag2)
{
return (tag1 & (~METHODMAPTAG)) == (tag2 & (~METHODMAPTAG));
}
/*
* Finds a function in the global symbol table or creates a new entry.
* It does some basic processing and error checking.
@ -4642,7 +4659,7 @@ SC_FUNC symbol *fetchfunc(char *name,int tag)
error(21,name); /* yes, and it is a native */
} /* if */
assert(sym->vclass==sGLOBAL);
if ((sym->usage & uPROTOTYPED)!=0 && sym->tag!=tag)
if ((sym->usage & uPROTOTYPED)!=0 && !compare_tag(sym->tag, tag))
error(25); /* mismatch from earlier prototype */
if ((sym->usage & uDEFINE)==0) {
/* as long as the function stays undefined, update the address and the tag */
@ -5331,11 +5348,7 @@ static int argcompare(arginfo *a1,arginfo *a2)
{
int result,level,i;
#if 0 /* SourceMod uses case insensitive args for forwards */
result= strcmp(a1->name,a2->name)==0; /* name */
#else
result=1;
#endif
if (result)
result= a1->ident==a2->ident; /* type/class */
if (result)
@ -5343,13 +5356,13 @@ static int argcompare(arginfo *a1,arginfo *a2)
if (result)
result= a1->numtags==a2->numtags; /* tags (number and names) */
for (i=0; result && i<a1->numtags; i++)
result= a1->tags[i]==a2->tags[i];
result= compare_tag(a1->tags[i], a2->tags[i]);
if (result)
result= a1->numdim==a2->numdim; /* array dimensions & index tags */
for (level=0; result && level<a1->numdim; level++)
result= a1->dim[level]==a2->dim[level];
for (level=0; result && level<a1->numdim; level++)
result= a1->idxtag[level]==a2->idxtag[level];
result= compare_tag(a1->idxtag[level], a2->idxtag[level]);
if (result)
result= a1->hasdefault==a2->hasdefault; /* availability of default value */
if (a1->hasdefault) {
@ -5372,7 +5385,7 @@ static int argcompare(arginfo *a1,arginfo *a2)
} /* if */
} /* if */
if (result)
result= a1->defvalue_tag==a2->defvalue_tag;
result= compare_tag(a1->defvalue_tag, a2->defvalue_tag);
} /* if */
return result;
}
@ -6537,7 +6550,7 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
*/
if (!redef)
goto redef_enumfield;
} else if (sym->tag!=tag) {
} else if (!compare_tag(sym->tag, tag)) {
redef=1; /* redefinition of a constant (non-enum) to a different tag is not allowed */
} /* if */
if (redef) {

View File

@ -3138,7 +3138,6 @@ SC_FUNC int matchtoken2(int id, token_t *tok)
if (matchtoken(id)) {
tok->id = tokeninfo(&tok->val, &tok->str);
return TRUE;
}
return FALSE;
}

View File

@ -23,6 +23,9 @@ stock E(E2 t)
{
}
stock F(int n[10]) {
}
public main()
{
new x[10]
@ -31,4 +34,5 @@ public main()
C(x)
D(E1:5)
E(E2:5)
F(x)
}

View File

@ -22,7 +22,7 @@ def run_tests(args):
kind = 'pass'
try:
argv = [args.spcomp, os.path.join(testdir, test + '.sp')]
argv = [os.path.abspath(args.spcomp), os.path.join(testdir, test + '.sp')]
p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
stdout = stdout.decode('utf-8')