3 # "This IS structured code. It's just randomly structured."
7 require "./test.pl"; require './charset_tools.pl';
8 set_up_inc( qw(. ../lib) );
17 local $SIG{__WARN__} = sub { if ($_[0] =~ m/jump into a construct/) { $deprecated++; } else { warn $_[0] } };
23 is($deprecated, 1, "following label1");
31 is($deprecated, 1, "following label3");
36 is($deprecated, 0, "after 'while' loop");
42 is($foo, 2, 'escape while loop');
43 is($deprecated, 0, "following label2");
47 is($foo, 4, 'second escape while loop');
49 my $r = run_perl(prog => 'goto foo;', stderr => 1);
50 like($r, qr/label/, 'cant find label');
61 ok($ok, 'goto in sub');
72 is(curr_test(), 20, 'FINALE');
74 # does goto LABEL handle block contexts correctly?
75 # note that this scope-hopping differs from last & next,
76 # which always go up-scope strictly.
87 is($count, 0, 'OTHER');
93 is($count, 1, 'THIRD');
97 is($count, 2, 'end of loop');
99 # Does goto work correctly within a for(;;) loop?
100 # (BUG ID 20010309.004 (#5998))
102 for(my $i=0;!$i++;) {
105 label: is($x, 1, 'goto inside a for(;;) loop body from inside the body');
108 # Does goto work correctly going *to* a for(;;) loop?
109 # (make sure it doesn't skip the initializer)
112 FORL1: for ($y=1; $z;) {
113 ok($y, 'goto a for(;;) loop, from outside (does initializer)');
118 # Even from within the loop?
120 FORL2: for($y=1; 1;) {
122 ok($y, 'goto a for(;;) loop, from inside (does initializer)');
129 # Does goto work correctly within a try block?
130 # (BUG ID 20000313.004) - [perl #2359]
135 LABEL20: $ok = 1 if $variable;
137 ok($ok, 'works correctly within a try block');
138 is($@, "", '...and $@ not set');
140 # And within an eval-string?
145 LABEL21: $ok = 1 if $variable;
147 ok($ok, 'works correctly within an eval string');
148 is($@, "", '...and $@ still not set');
151 # Test that goto works in nested eval-string
164 ok($ok, 'works correctly in a nested eval string');
171 { goto A; A: $ok = 1 } continue { }
172 ok($ok, '#20357 goto inside /{ } continue { }/ loop');
175 { do { goto A; A: $ok = 1 } while $false }
176 ok($ok, '#20154 goto inside /do { } while ()/ loop');
178 foreach(1) { goto A; A: $ok = 1 } continue { };
179 ok($ok, 'goto inside /foreach () { } continue { }/ loop');
183 A: { if ($false) { redo A; B: $ok = 1; redo A; } }
184 goto B unless $count++;
186 is($deprecated, 0, "before calling sub a()");
188 ok($ok, '#19061 loop label wiped away by goto');
189 is($deprecated, 1, "after calling sub a()");
194 for ($p=1;$p && goto A;$p=0) { A: $ok = 1 }
195 ok($ok, 'weird case of goto and for(;;) loop');
196 is($deprecated, 1, "following goto and for(;;) loop");
200 # bug #9990 - don't prematurely free the CV we're &going to.
204 goto sub { $x=0; ok(1,"don't prematurely free CV\n") }
208 # bug #99850, which is similar - freeing the subroutine we are about to
209 # go(in)to during a FREETMPS call should not crash perl.
213 DESTROY { undef &reftype }
214 eval { sub { my $guard = bless []; goto &reftype }->() };
216 like $@, qr/^Goto undefined subroutine &_99850::reftype at /,
217 'goto &foo undefining &foo on sub cleanup';
219 # When croaking after discovering that the new CV you're about to goto is
220 # undef, make sure that the old CV isn't doubly freed.
225 # creating a new closure here encourages any prematurely freed
226 # CV to be reallocated
227 sub DESTROY { undef &undef_sub; my $x = sub { $count } }
231 my $guard = bless []; # trigger DESTROY during goto
239 ::is($count, 10, "goto undef_sub safe");
242 # make sure that nothing nasty happens if the old CV is freed while
248 no warnings 'redefine';
252 sub g { $results = "(@_)" }
255 ::is($results, "(1 2 3)", "Free_cv");
259 # bug #22181 - this used to coredump or make $x undefined, due to
260 # erroneous popping of the inner BLOCK context
263 for ($count=0; $count<2; $count++) {
269 is($ok, 1, 'goto in for(;;) with continuation');
271 # bug #22299 - goto in require doesn't find label
273 open my $f, ">Op_goto01.pm" or die;
283 $r = runperl(prog => 'BEGIN { unshift @INC, q[.] } use Op_goto01; print qq[DONE\n]');
284 is($r, "OK\nDONE\n", "goto within use-d file");
285 unlink_all "Op_goto01.pm";
287 # test for [perl #24108]
290 sub i_return_a_label {
292 return "returned_label";
294 eval { goto +i_return_a_label; };
298 is($count, 1, 'called i_return_a_label');
299 ok($ok, 'skipped to returned_label');
301 # [perl #29708] - goto &foo could leave foo() at depth two with
302 # @_ == PL_sv_undef, causing a coredump
307 'sub f { return if $d; $d=1; my $a=sub {goto &f}; &$a; f() } f(); print qq(ok\n)',
310 is($r, "ok\n", 'avoid pad without an @_');
313 fail('goto moretests');
318 is(curr_test(), 9, 'eval "goto $x"');
320 # Test autoloading mechanism.
323 my ($pack, $file, $line) = caller; # Should indicate original call stats.
324 is("@_ $pack $file $line", "1 2 3 main $::FILE $::LINE",
325 'autoloading mechanism.');
330 no warnings 'redefine';
331 sub one { pass('sub one'); goto &two; fail('sub one tail'); }
337 $::LINE = __LINE__ + 1;
341 my $wherever = 'NOWHERE';
342 eval { goto $wherever };
343 like($@, qr/Can't find label NOWHERE/, 'goto NOWHERE sets $@');
346 # see if a modified @_ propagates
350 sub DESTROY { my $s = shift; ::is($s->[0], $i, "destroy $i"); }
351 sub show { ::is(+@_, 5, "show $i",); }
352 sub start { push @_, 1, "foo", {}; goto &show; }
353 for (1..3) { $i = $_; start(bless([$_]), 'bar'); }
360 sub AUTOLOAD { $ok = 1 if "@_" eq "foo" }
367 my $wherever = 'FINALE';
370 fail('goto $wherever');
373 # test goto duplicated labels.
379 L4: # not outer scope
386 like($@, qr/Can't "goto" into the middle of a foreach loop/,
387 'catch goto middle of foreach');
390 # ambiguous label resolution (outer scope means endless loop!)
394 is($z, 10, 'prefer same scope (loop body) to outer scope (loop entry)');
398 is($z, 10, 'prefer same scope: second');
406 is($z, 10, 'prefer this scope (block body) to outer scope (block entry)');
410 is($z, 10, 'prefer this scope: second');
417 L3: # not inner scope
421 is($z, 10, 'prefer this scope to inner scope');
425 is($z, 10, 'prefer this scope to inner scope: second');
428 L4: # not outer scope
432 L4: # not inner scope
436 is($z, 1, 'prefer this scope to inner,outer scopes');
440 is($z, 1, 'prefer this scope to inner,outer scopes: second');
446 L2: # without this, fails 1 (middle) out of 3 iterations
451 "same label, multiple times in same scope (choose 1st) $loop");
452 goto L2 if $z == 10 and not $loop++;
457 # This bug was introduced in Aug 2010 by commit ac56e7de46621c6f
458 # Peephole optimise adjacent pairs of nextstate ops.
459 # and fixed in Oct 2014 by commit f5b5c2a37af87535
460 # Simplify double-nextstate optimisation
462 # The bug manifests as a warning
463 # Use of "goto" to jump into a construct is deprecated at t/op/goto.t line 442.
464 # and $out is undefined. Devel::Peek reveals that the lexical in the pad has
465 # been reset to undef. I infer that pp_goto thinks that it's leaving one scope
466 # and entering another, but I don't know *why* it thinks that. Whilst this bug
467 # has been fixed by Father C, because I don't understand why it happened, I am
468 # not confident that other related bugs remain (or have always existed).
480 $out .= 'perl rules';
483 is($out, 'perl rules', '$out has not been erroneously reset to undef');
487 is($deprecated, 0, 'no warning was emmitted');
489 # deep recursion with gotos eventually caused a stack reallocation
490 # which messed up buggy internals that didn't expect the stack to move
494 no warnings 'recursion';
499 $_[0] ? +1 + recurse1($_[0] - 1) : 0
502 $SIG{__WARN__} = sub { ++$w };
503 is(recurse1(500), 500, 'recursive goto &foo');
504 is $w, 0, 'no recursion warnings for "no warnings; goto &sub"';
505 delete $SIG{__WARN__};
507 # [perl #32039] Chained goto &sub drops data too early.
509 sub a32039 { @_=("foo"); goto &b32039; }
510 sub b32039 { goto &c32039; }
511 sub c32039 { is($_[0], 'foo', 'chained &goto') }
514 # [perl #35214] next and redo re-entered the loop with the wrong cop,
515 # causing a subsequent goto to crash
521 'for ($_=0;$_<3;$_++){A: if($_==1){next} if($_==2){$_++;goto A}}print qq(ok\n)'
523 is($r, "ok\n", 'next and goto');
528 'for ($_=0;$_<3;$_++){A: if($_==1){$_++;redo} if($_==2){$_++;goto A}}print qq(ok\n)'
530 is($r, "ok\n", 'redo and goto');
533 # goto &foo not allowed in evals
537 like($@, qr/Can't goto subroutine from an eval-string/, 'eval string');
539 like($@, qr/Can't goto subroutine from an eval-block/, 'eval block');
541 # goto &foo leaves @_ alone when called from a sub
542 sub returnarg { $_[0] };
544 local *_ = ["ick and queasy"];
546 }->("quick and easy"), "ick and queasy",
547 'goto &foo with *_{ARRAY} replaced';
548 my @__ = byte_utf8a_to_utf8n("\xc4\x80");
549 sub { local *_ = \@__; goto &utf8::decode }->("no thinking aloud");
550 is "@__", chr 256, 'goto &xsub with replaced *_{ARRAY}';
552 # And goto &foo should leave reified @_ alone
553 sub { *__ = \@_; goto &null } -> ("rough and tubbery");
554 is ${*__}[0], 'rough and tubbery', 'goto &foo leaves reified @_ alone';
556 # goto &xsub when @_ has nonexistent elements
558 no warnings "uninitialized";
561 & {sub { goto &utf8::encode }};
562 is @_, 1, 'num of elems in @_ after goto &xsub with nonexistent $_[0]';
563 is $_[0], "", 'content of nonexistent $_[0] is modified by goto &xsub';
566 # goto &xsub when @_ itself does not exist
568 eval { & { sub { goto &utf8::encode } } };
569 # The main thing we are testing is that it did not crash. But make sure
570 # *_{ARRAY} was untouched, too.
571 is *_{ARRAY}, undef, 'goto &xsub when @_ does not exist';
573 # goto &perlsub when @_ itself does not exist [perl #119949]
574 # This was only crashing when the replaced sub call had an argument list.
575 # (I.e., &{ sub { goto ... } } did not crash.)
579 is *_{ARRAY}, undef, 'goto &perlsub when @_ does not exist';
585 is *_{ARRAY}, undef, 'goto &sub when @_ does not exist (local *_)';
590 # [perl #36521] goto &foo in warn handler could defeat recursion avoider
595 prog => 'my $d; my $w = sub { return if $d++; warn q(bar)}; local $SIG{__WARN__} = sub { goto &$w; }; warn q(foo);'
597 like($r, qr/bar/, "goto &foo in warn");
601 local $TODO = "[perl #43403] goto() from an if to an else doesn't undo local () changes";
602 our $global = "unmodified";
603 if ($global) { # true but not constant-folded
604 local $global = "modified";
607 ELSE: is($global, "unmodified");
611 is($deprecated, 0, "following TODOed test for #43403");
617 F1:++$x and eval 'return if ++$y == 10; goto F1;';
619 'labels outside evals can be distinguished from the start of the eval');
623 die "You can't get here";
626 ouch_eth: pass('labels persist even if their statement is optimised away');
639 skip_if_miniperl("no dynamic loading on miniperl, so can't load PerlIO::scalar", 1);
641 open(CHOLET, ">", \$cholet);
644 $foo .= "(".$cholet.")";
645 is($foo, "(0)(1)(wellington\n)", "label before format decl");
654 sub alderney { return "tobermory"; }
656 $foo .= "(".alderney().")";
657 is($foo, "(A)(B)(tobermory)", "label before sub decl");
659 $foo = "[0:".__PACKAGE__."]";
666 $foo .= "[1:".__PACKAGE__."]";
667 $foo .= "[2:".__PACKAGE__."]";
669 $foo .= "[3:".__PACKAGE__."]";
670 is($foo, "[0:main][1:Tomsk][2:Tomsk][3:main]", "label before package decl");
672 $foo = "[A:".__PACKAGE__."]";
679 $foo .= "[B:".__PACKAGE__."]";
681 $foo .= "[C:".__PACKAGE__."]";
682 is($foo, "[A:main][B:Cairngorm][C:main]", "label before package block");
691 BEGIN { $obidos = "x"; }
692 $foo .= "{1$obidos}";
693 is($foo, "{0}{1x}", "label before BEGIN block");
695 $foo = "{A:".(1.5+1.5)."}";
702 $foo .= "{B:".(1.5+1.5)."}";
703 is($foo, "{A:3}{B:2}", "label before use decl");
713 is($foo, "<0><1><2>", "first of three stacked labels");
723 is($foo, "<A><B><C>", "second of three stacked labels");
733 is($foo, ",0.,1.,2.", "third of three stacked labels");
735 # [perl #112316] Wrong behavior regarding labels with same prefix
736 sub same_prefix_labels {
742 if ( !$first_time ) {
756 same_prefix_labels(),
757 "perl 112316: goto and labels with the same prefix doesn't get mixed up"
760 eval { my $x = ""; goto $x };
761 like $@, qr/^goto must have label at /, 'goto $x where $x is empty string';
763 like $@, qr/^goto must have label at /, 'goto ""';
765 like $@, qr/^goto must have label at /, 'argless goto';
767 eval { my $x = "\0"; goto $x };
768 like $@, qr/^Can't find label \0 at /, 'goto $x where $x begins with \0';
770 like $@, qr/^Can't find label \0 at /, 'goto "\0"';
772 sub TIESCALAR { bless [pop] }
773 sub FETCH { $_[0][0] }
774 tie my $t, "", sub { "cluck up porridge" };
775 is eval { sub { goto $t }->() }//$@, 'cluck up porridge',
776 'tied arg returning sub ref';
779 local $::TODO = 'RT #45091: goto in CORE::GLOBAL::exit unsupported';
780 fresh_perl_is(<<'EOC', "before\ndie handler\n", {stderr => 1}, 'RT #45091: goto in CORE::GLOBAL::EXIT');
782 *CORE::GLOBAL::exit = sub {
783 goto FASTCGI_NEXT_REQUEST;
787 eval { that_cgi_script() };
788 FASTCGI_NEXT_REQUEST:
792 sub that_cgi_script {
793 local $SIG{__DIE__} = sub { print "die handler\n"; exit; print "exit failed?\n"; };
795 eval { buggy_code() };