diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-18 12:03:54 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-05-18 12:03:54 -0300 |
commit | 6d53701c7a0dc4736d824fd891ee6f22265d0d68 (patch) | |
tree | 74876c6991b50c0327012e9cb9a3dc282925767d | |
parent | abbae57c7844b1121e7251d56f681394f20c1821 (diff) | |
download | lua-6d53701c7a0dc4736d824fd891ee6f22265d0d68.tar.gz lua-6d53701c7a0dc4736d824fd891ee6f22265d0d68.tar.bz2 lua-6d53701c7a0dc4736d824fd891ee6f22265d0d68.zip |
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.
-rw-r--r-- | lparser.c | 6 | ||||
-rw-r--r-- | manual/manual.of | 2 | ||||
-rw-r--r-- | testes/goto.lua | 13 |
3 files changed, 12 insertions, 9 deletions
@@ -542,13 +542,13 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | |||
542 | 542 | ||
543 | /* | 543 | /* |
544 | ** Generates an error that a goto jumps into the scope of some | 544 | ** Generates an error that a goto jumps into the scope of some |
545 | ** local variable. | 545 | ** variable declaration. |
546 | */ | 546 | */ |
547 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { | 547 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { |
548 | TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name; | 548 | TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name; |
549 | const char *varname = getstr(tsname); | 549 | const char *varname = (tsname != NULL) ? getstr(tsname) : "*"; |
550 | luaK_semerror(ls, | 550 | luaK_semerror(ls, |
551 | "<goto %s> at line %d jumps into the scope of local '%s'", | 551 | "<goto %s> at line %d jumps into the scope of '%s'", |
552 | getstr(gt->name), gt->line, varname); /* raise the error */ | 552 | getstr(gt->name), gt->line, varname); /* raise the error */ |
553 | } | 553 | } |
554 | 554 | ||
diff --git a/manual/manual.of b/manual/manual.of index eb97e853..a6361fa2 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -1504,7 +1504,7 @@ labels in Lua are considered statements too: | |||
1504 | A label is visible in the entire block where it is defined, | 1504 | A label is visible in the entire block where it is defined, |
1505 | except inside nested functions. | 1505 | except inside nested functions. |
1506 | A goto can jump to any visible label as long as it does not | 1506 | A goto can jump to any visible label as long as it does not |
1507 | enter into the scope of a local variable. | 1507 | enter into the scope of a variable declaration. |
1508 | A label should not be declared | 1508 | A label should not be declared |
1509 | where a previous label with the same name is visible, | 1509 | where a previous label with the same name is visible, |
1510 | even if this other label has been declared in an enclosing block. | 1510 | even if this other label has been declared in an enclosing block. |
diff --git a/testes/goto.lua b/testes/goto.lua index 44486e20..d7730061 100644 --- a/testes/goto.lua +++ b/testes/goto.lua | |||
@@ -23,15 +23,18 @@ errmsg([[ ::l1:: ::l1:: ]], "label 'l1'") | |||
23 | errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") | 23 | errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") |
24 | 24 | ||
25 | 25 | ||
26 | -- undefined label | ||
27 | errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'") | ||
28 | 26 | ||
29 | -- jumping over variable definition | 27 | -- jumping over variable declaration |
28 | errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "scope of 'aa'") | ||
29 | |||
30 | errmsg([[ goto l2; global *; ::l1:: ::l2:: print(3) ]], "scope of '*'") | ||
31 | |||
30 | errmsg([[ | 32 | errmsg([[ |
31 | do local bb, cc; goto l1; end | 33 | do local bb, cc; goto l1; end |
32 | local aa | 34 | local aa |
33 | ::l1:: print(3) | 35 | ::l1:: print(3) |
34 | ]], "local 'aa'") | 36 | ]], "scope of 'aa'") |
37 | |||
35 | 38 | ||
36 | -- jumping into a block | 39 | -- jumping into a block |
37 | errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") | 40 | errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") |
@@ -44,7 +47,7 @@ errmsg([[ | |||
44 | local xuxu = 10 | 47 | local xuxu = 10 |
45 | ::cont:: | 48 | ::cont:: |
46 | until xuxu < x | 49 | until xuxu < x |
47 | ]], "local 'xuxu'") | 50 | ]], "scope of 'xuxu'") |
48 | 51 | ||
49 | -- simple gotos | 52 | -- simple gotos |
50 | local x | 53 | local x |