Proper error message when jumping into 'global *'

A goto cannot jump into the scope of any variable declaration,
including 'global *'. To report the error, it needs a "name" for
the scope it is entering.
This commit is contained in:
Roberto Ierusalimschy
2025-05-18 12:03:54 -03:00
parent abbae57c78
commit 6d53701c7a
3 changed files with 12 additions and 9 deletions

View File

@@ -542,13 +542,13 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
/* /*
** Generates an error that a goto jumps into the scope of some ** Generates an error that a goto jumps into the scope of some
** local variable. ** variable declaration.
*/ */
static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name; TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name;
const char *varname = getstr(tsname); const char *varname = (tsname != NULL) ? getstr(tsname) : "*";
luaK_semerror(ls, luaK_semerror(ls,
"<goto %s> at line %d jumps into the scope of local '%s'", "<goto %s> at line %d jumps into the scope of '%s'",
getstr(gt->name), gt->line, varname); /* raise the error */ getstr(gt->name), gt->line, varname); /* raise the error */
} }

View File

@@ -1504,7 +1504,7 @@ labels in Lua are considered statements too:
A label is visible in the entire block where it is defined, A label is visible in the entire block where it is defined,
except inside nested functions. except inside nested functions.
A goto can jump to any visible label as long as it does not A goto can jump to any visible label as long as it does not
enter into the scope of a local variable. enter into the scope of a variable declaration.
A label should not be declared A label should not be declared
where a previous label with the same name is visible, where a previous label with the same name is visible,
even if this other label has been declared in an enclosing block. even if this other label has been declared in an enclosing block.

View File

@@ -23,15 +23,18 @@ errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'")
-- undefined label
errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")
-- jumping over variable definition -- jumping over variable declaration
errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "scope of 'aa'")
errmsg([[ goto l2; global *; ::l1:: ::l2:: print(3) ]], "scope of '*'")
errmsg([[ errmsg([[
do local bb, cc; goto l1; end do local bb, cc; goto l1; end
local aa local aa
::l1:: print(3) ::l1:: print(3)
]], "local 'aa'") ]], "scope of 'aa'")
-- jumping into a block -- jumping into a block
errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
@@ -44,7 +47,7 @@ errmsg([[
local xuxu = 10 local xuxu = 10
::cont:: ::cont::
until xuxu < x until xuxu < x
]], "local 'xuxu'") ]], "scope of 'xuxu'")
-- simple gotos -- simple gotos
local x local x