aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-30 15:46:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-30 15:46:56 -0300
commite073cbc2e538369e0611abfc9948f301aea6aef3 (patch)
tree6ef30a285092e8bcc15021b1d857a62dbab36fd6
parent2316ec4c24a475e091ec3153a5bd908801a3a109 (diff)
downloadlua-e073cbc2e538369e0611abfc9948f301aea6aef3.tar.gz
lua-e073cbc2e538369e0611abfc9948f301aea6aef3.tar.bz2
lua-e073cbc2e538369e0611abfc9948f301aea6aef3.zip
Better error messages for invalid operands in numeric 'for'
"Better" and similar to error messages for invalid function arguments. *old message: 'for' limit must be a number *new message: bad 'for' limit (number expected, got table)
-rw-r--r--ldebug.c6
-rw-r--r--ldebug.h2
-rw-r--r--lvm.c8
-rw-r--r--testes/errors.lua10
4 files changed, 22 insertions, 4 deletions
diff --git a/ldebug.c b/ldebug.c
index 3590010c..ee1b87d9 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -696,6 +696,12 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
696} 696}
697 697
698 698
699l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) {
700 luaG_runerror(L, "bad 'for' %s (number expected, got %s)",
701 what, luaT_objtypename(L, o));
702}
703
704
699l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { 705l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
700 if (ttisstring(p1) || cvt2str(p1)) p1 = p2; 706 if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
701 luaG_typeerror(L, p1, "concatenate"); 707 luaG_typeerror(L, p1, "concatenate");
diff --git a/ldebug.h b/ldebug.h
index 31ecc2f6..f080711d 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -24,6 +24,8 @@
24LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 24LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc);
25LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 25LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
26 const char *opname); 26 const char *opname);
27LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o,
28 const char *what);
27LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 29LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
28 const TValue *p2); 30 const TValue *p2);
29LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 31LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
diff --git a/lvm.c b/lvm.c
index 35a58089..aad965d6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1681,7 +1681,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1681 int stopnow; 1681 int stopnow;
1682 if (unlikely(!forlimit(plimit, &ilimit, 1, &stopnow))) { 1682 if (unlikely(!forlimit(plimit, &ilimit, 1, &stopnow))) {
1683 savestate(L, ci); /* for the error message */ 1683 savestate(L, ci); /* for the error message */
1684 luaG_runerror(L, "'for' limit must be a number"); 1684 luaG_forerror(L, plimit, "limit");
1685 } 1685 }
1686 initv = (stopnow ? 0 : ivalue(init)); 1686 initv = (stopnow ? 0 : ivalue(init));
1687 setivalue(plimit, ilimit); 1687 setivalue(plimit, ilimit);
@@ -1732,13 +1732,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1732 lua_Number ninit; lua_Number nlimit; lua_Number nstep; 1732 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
1733 savestate(L, ci); /* in case of errors */ 1733 savestate(L, ci); /* in case of errors */
1734 if (unlikely(!tonumber(plimit, &nlimit))) 1734 if (unlikely(!tonumber(plimit, &nlimit)))
1735 luaG_runerror(L, "'for' limit must be a number"); 1735 luaG_forerror(L, plimit, "limit");
1736 setfltvalue(plimit, nlimit); 1736 setfltvalue(plimit, nlimit);
1737 if (unlikely(!tonumber(pstep, &nstep))) 1737 if (unlikely(!tonumber(pstep, &nstep)))
1738 luaG_runerror(L, "'for' step must be a number"); 1738 luaG_forerror(L, pstep, "step");
1739 setfltvalue(pstep, nstep); 1739 setfltvalue(pstep, nstep);
1740 if (unlikely(!tonumber(init, &ninit))) 1740 if (unlikely(!tonumber(init, &ninit)))
1741 luaG_runerror(L, "'for' initial value must be a number"); 1741 luaG_forerror(L, init, "initial value");
1742 setfltvalue(init, luai_numsub(L, ninit, nstep)); 1742 setfltvalue(init, luai_numsub(L, ninit, nstep));
1743 } 1743 }
1744 pc += GETARG_Bx(i); 1744 pc += GETARG_Bx(i);
diff --git a/testes/errors.lua b/testes/errors.lua
index 142e8b33..74975e31 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -154,6 +154,16 @@ checkmessage("a = 24 // 0", "divide by zero")
154checkmessage("a = 1 % 0", "'n%0'") 154checkmessage("a = 1 % 0", "'n%0'")
155 155
156 156
157-- numeric for loops
158checkmessage("for i = {}, 10 do end", "table")
159checkmessage("for i = io.stdin, 10 do end", "FILE")
160checkmessage("for i = {}, 10 do end", "initial value")
161checkmessage("for i = 1, 'x', 10 do end", "string")
162checkmessage("for i = 1, {}, 10 do end", "limit")
163checkmessage("for i = 1, {} do end", "limit")
164checkmessage("for i = 1, 10, print do end", "step")
165checkmessage("for i = 1, 10, print do end", "function")
166
157-- passing light userdata instead of full userdata 167-- passing light userdata instead of full userdata
158_G.D = debug 168_G.D = debug
159checkmessage([[ 169checkmessage([[