diff --git a/sourcepawn/compiler/sc3.cpp b/sourcepawn/compiler/sc3.cpp index e7c5dd5b..7b5e6d00 100644 --- a/sourcepawn/compiler/sc3.cpp +++ b/sourcepawn/compiler/sc3.cpp @@ -329,10 +329,12 @@ const char *type_to_name(int tag) return "float"; if (tag == pc_tag_string) return "char"; + if (tag == pc_anytag) + return "any"; const char *name = pc_tagname(tag); if (name) - return NULL; + return "unknown"; if (tag & FUNCTAG) return "function"; @@ -1340,8 +1342,15 @@ 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 && !checktag_string(&lval3, &lval2)) - matchtag(lval3.tag,lval2.tag,TRUE); + if (!oper && !checktag_string(&lval3, &lval2)) { + if ((lval3.tag == pc_tag_string && lval2.tag != pc_tag_string) || + (lval3.tag != pc_tag_string && lval2.tag == pc_tag_string)) + { + error(179, type_to_name(lval3.tag), type_to_name(lval2.tag)); + } else { + matchtag(lval3.tag,lval2.tag,TRUE); + } + } if (lval3.sym) markusage(lval3.sym,uWRITTEN); sideeffect=TRUE; @@ -2931,7 +2940,17 @@ static int nesting=0; append_constval(&arrayszlst,arg[argidx].name,sym->dim.array.length,level); } /* if */ /* address already in PRI */ + checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag); + + if (arg[argidx].numtags > 0) { + if ((arg[argidx].tags[0] != pc_tag_string && lval.tag == pc_tag_string) || + (arg[argidx].tags[0] == pc_tag_string && lval.tag != pc_tag_string)) + { + error(178, type_to_name(lval.tag), type_to_name(arg[argidx].tags[0])); + } + } + if (lval.tag!=0) append_constval(&taglst,arg[argidx].name,lval.tag,0); // ??? set uWRITTEN? diff --git a/sourcepawn/compiler/sc5-in.scp b/sourcepawn/compiler/sc5-in.scp index 7968cf5b..064ffd4b 100644 --- a/sourcepawn/compiler/sc5-in.scp +++ b/sourcepawn/compiler/sc5-in.scp @@ -221,6 +221,8 @@ static const char *errmsg[] = { /*175*/ "constructors cannot be static\n", /*176*/ "non-static method or property '%s' must be called with a value of type '%s'\n", /*177*/ "static method '%s' must be invoked via its type (try '%s.%s')\n", +/*178*/ "cannot coerce %s[] to %s[]; storage classes differ\n", +/*179*/ "cannot assign %s[] to %s[], storage classes differ\n", #else "\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012", "\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012", diff --git a/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.sp b/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.sp new file mode 100644 index 00000000..d7f34615 --- /dev/null +++ b/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.sp @@ -0,0 +1,7 @@ +public main() +{ + char x[40]; + any y[10]; + x = y; + y = x; +} diff --git a/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.txt b/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.txt new file mode 100644 index 00000000..102dad96 --- /dev/null +++ b/sourcepawn/compiler/tests/fail-assign-string-and-nonstring.txt @@ -0,0 +1,2 @@ +(5) : error 179: cannot assign char[] to any[], storage classes differ +(6) : error 179: cannot assign any[] to char[], storage classes differ diff --git a/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.sp b/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.sp new file mode 100644 index 00000000..fc48d671 --- /dev/null +++ b/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.sp @@ -0,0 +1,9 @@ +f(any[] x) +{ +} + +public main() +{ + char x[10]; + f(x[1]); +} diff --git a/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.txt b/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.txt new file mode 100644 index 00000000..4d668d2b --- /dev/null +++ b/sourcepawn/compiler/tests/fail-coerce-ref-string-to-any.txt @@ -0,0 +1 @@ +(8) : error 178: cannot coerce char[] to any[]; storage classes differ diff --git a/sourcepawn/compiler/tests/fail-coerce-string-to-any.sp b/sourcepawn/compiler/tests/fail-coerce-string-to-any.sp new file mode 100644 index 00000000..296f47cb --- /dev/null +++ b/sourcepawn/compiler/tests/fail-coerce-string-to-any.sp @@ -0,0 +1,9 @@ +f(any[] x) +{ +} + +public main() +{ + char x[10]; + f(x); +} diff --git a/sourcepawn/compiler/tests/fail-coerce-string-to-any.txt b/sourcepawn/compiler/tests/fail-coerce-string-to-any.txt new file mode 100644 index 00000000..4d668d2b --- /dev/null +++ b/sourcepawn/compiler/tests/fail-coerce-string-to-any.txt @@ -0,0 +1 @@ +(8) : error 178: cannot coerce char[] to any[]; storage classes differ diff --git a/sourcepawn/compiler/tests/ok-typed-vararg-in-new-function.sp b/sourcepawn/compiler/tests/ok-typed-vararg-in-new-function.sp index 62b1d66a..3be4a63f 100644 --- a/sourcepawn/compiler/tests/ok-typed-vararg-in-new-function.sp +++ b/sourcepawn/compiler/tests/ok-typed-vararg-in-new-function.sp @@ -1,3 +1,7 @@ methodmap X { public native void egg(any ...); }; + +public main() +{ +}