Browse Source

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.
Roberto Ierusalimschy 2 months ago
parent
commit
6d53701c7a
3 changed files with 12 additions and 9 deletions
  1. 3 3
      lparser.c
  2. 1 1
      manual/manual.of
  3. 8 5
      testes/goto.lua

+ 3 - 3
lparser.c

@@ -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 */
 }
 }
 
 

+ 1 - 1
manual/manual.of

@@ -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.

+ 8 - 5
testes/goto.lua

@@ -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