Compiler: Fix runtime error in variadic functions that return strings.

Imported from SM-AM: 1d1244c2f0.

"This fixes a bug where returning a string from a variadic function caused
an invalid memory access error during runtime. It seems like they forgot
to update existing string return code for variadic functions."
This commit is contained in:
Arkshine
2014-08-15 17:15:22 +02:00
parent 1866afd80b
commit 17114347d1
3 changed files with 53 additions and 1 deletions

View File

@@ -5288,6 +5288,22 @@ static symbol *fetchlab(char *name)
return sym;
}
/* isvariadic
*
* Checks if the function is variadic.
*/
static int isvariadic(symbol *sym)
{
int i;
for (i=0; curfunc->dim.arglist[i].ident!=0; i++) {
/* check whether this is a variadic function */
if (curfunc->dim.arglist[i].ident==iVARARGS) {
return TRUE;
} /* if */
} /* for */
return FALSE;
}
/* doreturn
*
* Global references: rettype (altered)
@@ -5392,7 +5408,19 @@ static void doreturn(void)
* it stays on the heap for the moment, and it is removed -usually- at
* the end of the expression/statement, see expression() in SC3.C)
*/
address(sub,sALT); /* ALT = destination */
if (isvariadic(sub)) {
pushreg(sPRI); /* save source address stored in PRI */
sub->addr=2*sizeof(cell);
address(sub,sALT); /* get the number of arguments */
getfrm();
addconst(3*sizeof(cell));
ob_add();
dereference();
swap1();
popreg(sALT); /* ALT = destination */
} else {
address(sub,sALT); /* ALT = destination */
} /* if */
arraysize=calc_arraysize(dim,numdim,0);
memcopy(arraysize*sizeof(cell)); /* source already in PRI */
/* moveto1(); is not necessary, callfunction() does a popreg() */