diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-03-02 13:24:06 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-03-02 13:24:06 -0300 |
commit | e4607523234f16ed9ed0436340b9315377dbfe7f (patch) | |
tree | ef792ad6ad9bd869c60b9a31539234e04dfa024a | |
parent | 92594f09395800f6f085ca7501ffd1f7aef25e22 (diff) | |
download | lua-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.c | 7 | ||||
-rw-r--r-- | lparser.c | 3 |
2 files changed, 5 insertions, 5 deletions
@@ -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); } @@ -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; |