Fix compile crash when returning a string literal

This fixes a crash during compile-time when returning a string or array
literal from a function. Now the compiler will give an error instead.

See 1) here: http://forum.sa-mp.com/showthread.php?t=355877

--------- test code --------

native use(...);

return_string() {
	new string[] = "string";
	return string;
}

return_string_literal() {
	return "string"; // error 029: invalid expression, assumed zero
}

return_number() {
	return 0;
}

main() {
	new n = return_number(); // OK
	new s[100];
	s = return_string(); // OK
	s = return_string_literal(); // error 033: array must be indexed (variable "s")
	use(n, s);
}

----- end of test code -----
This commit is contained in:
Zeex 2014-01-01 16:22:05 +07:00
parent c20d9cb33b
commit 6133e9d183

View File

@ -5621,7 +5621,7 @@ static void doreturn(void)
if ((rettype & uRETVALUE)!=0) { if ((rettype & uRETVALUE)!=0) {
int retarray=(ident==iARRAY || ident==iREFARRAY); int retarray=(ident==iARRAY || ident==iREFARRAY);
/* there was an earlier "return" statement in this function */ /* there was an earlier "return" statement in this function */
if (sub==NULL && retarray || sub!=NULL && !retarray) if ((sub==NULL && retarray && sym!=NULL) || sub!=NULL && !retarray)
error(79); /* mixing "return array;" and "return value;" */ error(79); /* mixing "return array;" and "return value;" */
if (retarray && (curfunc->usage & uPUBLIC)!=0) if (retarray && (curfunc->usage & uPUBLIC)!=0)
error(90,curfunc->name); /* public function may not return array */ error(90,curfunc->name); /* public function may not return array */
@ -5634,7 +5634,10 @@ static void doreturn(void)
if (ident==iARRAY || ident==iREFARRAY) { if (ident==iARRAY || ident==iREFARRAY) {
int dim[sDIMEN_MAX],numdim; int dim[sDIMEN_MAX],numdim;
cell arraysize; cell arraysize;
assert(sym!=NULL); if (sym==NULL) {
/* array literals cannot be returned directly */
error(29); /* invalid expression, assumed zero */
} else {
if (sub!=NULL) { if (sub!=NULL) {
assert(sub->ident==iREFARRAY); assert(sub->ident==iREFARRAY);
/* this function has an array attached already; check that the current /* this function has an array attached already; check that the current
@ -5705,6 +5708,7 @@ static void doreturn(void)
memcopy(arraysize*sizeof(cell)); /* source already in PRI */ memcopy(arraysize*sizeof(cell)); /* source already in PRI */
/* moveto1(); is not necessary, callfunction() does a popreg() */ /* moveto1(); is not necessary, callfunction() does a popreg() */
} /* if */ } /* if */
} /* if */
} else { } else {
/* this return statement contains no expression */ /* this return statement contains no expression */
ldconst(0,sPRI); ldconst(0,sPRI);