From ed4cca0225b0315149381728bd6cfdedecb89d01 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 3 Jul 2014 00:14:12 -0700 Subject: [PATCH] Bug fixes. --- sourcepawn/compiler/sc.h | 4 ++- sourcepawn/compiler/sc1.c | 33 +++++++++++++------ sourcepawn/compiler/sc2.c | 1 - sourcepawn/compiler/tests/ok-new-decl-args.sp | 4 +++ sourcepawn/compiler/tests/runtests.py | 2 +- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index a8682e6e..2fb0a391 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -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 */ diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index bc6dcfff..464d9546 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -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 && inumtags; 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 && levelnumdim; level++) result= a1->dim[level]==a2->dim[level]; for (level=0; result && levelnumdim; 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) { diff --git a/sourcepawn/compiler/sc2.c b/sourcepawn/compiler/sc2.c index 9a94a880..65623bea 100644 --- a/sourcepawn/compiler/sc2.c +++ b/sourcepawn/compiler/sc2.c @@ -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; } diff --git a/sourcepawn/compiler/tests/ok-new-decl-args.sp b/sourcepawn/compiler/tests/ok-new-decl-args.sp index 79d813ca..d938312b 100644 --- a/sourcepawn/compiler/tests/ok-new-decl-args.sp +++ b/sourcepawn/compiler/tests/ok-new-decl-args.sp @@ -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) } diff --git a/sourcepawn/compiler/tests/runtests.py b/sourcepawn/compiler/tests/runtests.py index 0c03b064..ac4c7c30 100644 --- a/sourcepawn/compiler/tests/runtests.py +++ b/sourcepawn/compiler/tests/runtests.py @@ -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')