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 |
