summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-03-02 13:24:06 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-03-02 13:24:06 -0300
commite4607523234f16ed9ed0436340b9315377dbfe7f (patch)
treeef792ad6ad9bd869c60b9a31539234e04dfa024a
parent92594f09395800f6f085ca7501ffd1f7aef25e22 (diff)
downloadlua-github-e4607523234f16ed9ed0436340b9315377dbfe7f.tar.gz
Fixed "conceptual" bug in 'luaK_setreturns'
This function was computing invalid instruction addresses when the expression was not a multi-return instruction. (Virtually all machines don't raise errors when computing an invalid address, as long as the address is not accessed, but this computation is undefined behavior in ISO C.)
-rw-r--r--lcode.c7
-rw-r--r--lparser.c3
2 files changed, 5 insertions, 5 deletions
diff --git a/lcode.c b/lcode.c
index 83a6d064..6f241c94 100644
--- a/lcode.c
+++ b/lcode.c
@@ -703,19 +703,18 @@ static void const2exp (TValue *v, expdesc *e) {
/*
** Fix an expression to return the number of results 'nresults'.
-** Either 'e' is a multi-ret expression (function call or vararg)
-** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
+** 'e' must be a multi-ret expression (function call or vararg).
*/
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
Instruction *pc = &getinstruction(fs, e);
if (e->k == VCALL) /* expression is an open function call? */
SETARG_C(*pc, nresults + 1);
- else if (e->k == VVARARG) {
+ else {
+ lua_assert(e->k == VVARARG);
SETARG_C(*pc, nresults + 1);
SETARG_A(*pc, fs->freereg);
luaK_reserveregs(fs, 1);
}
- else lua_assert(nresults == LUA_MULTRET);
}
diff --git a/lparser.c b/lparser.c
index 8c812039..b0dbb65c 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1014,7 +1014,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) {
args.k = VVOID;
else {
explist(ls, &args);
- luaK_setmultret(fs, &args);
+ if (hasmultret(args.k))
+ luaK_setmultret(fs, &args);
}
check_match(ls, ')', '(', line);
break;