Open djerius opened 1 month ago
Duplicate labels in the same scope are commonly used in tests:
SKIP:
{
skip "I can't test this", 1 if $cant_test_this;
...
}
SKIP:
{
skip "I can't test that", 1 if $cant_test_that;
...
}
so we can't just warn on duplicate labels in the same scope.
This means the optimization is changing the behavior of code outside of the optimized out part, which shouldn't happen.
This is documented in perlsyn and perlfunc:
... It also can't be used to go into a construct that is optimized away. ...
Of course, there's no requirement that the label is defined in the function containing the goto:
tony@venus:.../git/perl6$ cat ../22088b.pl
use v5.38;
sub f {
say "f";
goto X;
}
f();
goto Y;
X: { say "X1"; }
goto Y;
X: { say "X2"; }
Y:
{
f();
X: say "X3";
}
tony@venus:.../git/perl6$ ./perl -Ilib ../22088b.pl
f
X1
f
X3
I do think how this is resolved could be better documented.
Duplicate labels in the same scope are commonly used in tests:
SKIP: { skip "I can't test this", 1 if $cant_test_this; ... } SKIP: { skip "I can't test that", 1 if $cant_test_that; ... }
so we can't just warn on duplicate labels in the same scope.
Darn. Is there a way to differentiate between goto
and the loop control statements that must be used within the block they address (skip
uses last
under the hood)? It'd have to be a run-time error, as goto
can take an expression; maybe a flag on a label indicating it's multiply defined so that when goto
uses it it knows it's degenerate.
This is documented in perlsyn and perlfunc:
... It also can't be used to go into a construct that is optimized away. ...
Well, so much for my reading comprehension. Thanks for pointing that bit out, somehow I glossed over that. Since there's no official "guide to what gets optimized away" perhaps that should be written in bold and prefaced with "Here be dragons".
One documentation tweak might be to suggest use of redo
rather than goto
when jumping to the beginning of a labeled block from within it. I've modified my code to do that, so the multiple definition issue is resolved.
Description
Two issues, one documentation, one behavior.
Documentation: perlsyn doesn't document the scope of labels and what happens if a label is redefined.
Behavior
Here's what happens if the loop labels are in the same scope:
Looks like the repeated label is ignored. That's unexpected. It should be an error if one shouldn't repeat labels.
What if they are in separate blocks?
Looks like they are treated as separate labels, which is what I'd expect.
What if they are declared in blocks in a conditional?
Oops; the second one is ignored, even though it's in a new block. That is definitely not what I expected. I expected this situation to mirror the second example.
Note that if the first branch of the conditional is optimized out (see below), the first label isn't defined, and the second branch sees its own label. This means the optimization is changing the behavior of code outside of the optimized out part, which shouldn't happen. I think the above behavior is a bug.
Expected behavior
Perl configuration