3 # "This IS structured code. It's just randomly structured."
8 set_up_inc( qw(. ../lib) );
9 require './charset_tools.pl';
18 local $SIG{__WARN__} = sub { if ($_[0] =~ m/jump into a construct/) { $deprecated++; } else { warn $_[0] } };
24 is($deprecated, 1, "following label1");
32 is($deprecated, 1, "following label3");
37 is($deprecated, 0, "after 'while' loop");
43 is($foo, 2, 'escape while loop');
44 is($deprecated, 0, "following label2");
48 is($foo, 4, 'second escape while loop');
50 my $r = run_perl(prog => 'goto foo;', stderr => 1);
51 like($r, qr/label/, 'cant find label');
62 ok($ok, 'goto in sub');
73 is(curr_test(), 20, 'FINALE');
75 # does goto LABEL handle block contexts correctly?
76 # note that this scope-hopping differs from last & next,
77 # which always go up-scope strictly.
88 is($count, 0, 'OTHER');
94 is($count, 1, 'THIRD');
98 is($count, 2, 'end of loop');
100 # Does goto work correctly within a for(;;) loop?
101 # (BUG ID 20010309.004 (#5998))
103 for(my $i=0;!$i++;) {
106 label: is($x, 1, 'goto inside a for(;;) loop body from inside the body');
109 # Does goto work correctly going *to* a for(;;) loop?
110 # (make sure it doesn't skip the initializer)
113 FORL1: for ($y=1; $z;) {
114 ok($y, 'goto a for(;;) loop, from outside (does initializer)');
119 # Even from within the loop?
121 FORL2: for($y=1; 1;) {
123 ok($y, 'goto a for(;;) loop, from inside (does initializer)');
130 # Does goto work correctly within a try block?
131 # (BUG ID 20000313.004) - [perl #2359]
136 LABEL20: $ok = 1 if $variable;
138 ok($ok, 'works correctly within a try block');
139 is($@, "", '...and $@ not set');
141 # And within an eval-string?
146 LABEL21: $ok = 1 if $variable;
148 ok($ok, 'works correctly within an eval string');
149 is($@, "", '...and $@ still not set');
152 # Test that goto works in nested eval-string
165 ok($ok, 'works correctly in a nested eval string');
172 { goto A; A: $ok = 1 } continue { }
173 ok($ok, '#20357 goto inside /{ } continue { }/ loop');
176 { do { goto A; A: $ok = 1 } while $false }
177 ok($ok, '#20154 goto inside /do { } while ()/ loop');
179 foreach(1) { goto A; A: $ok = 1 } continue { };
180 ok($ok, 'goto inside /foreach () { } continue { }/ loop');
184 A: { if ($false) { redo A; B: $ok = 1; redo A; } }
185 goto B unless $count++;
187 is($deprecated, 0, "before calling sub a()");
189 ok($ok, '#19061 loop label wiped away by goto');
190 is($deprecated, 1, "after calling sub a()");
195 for ($p=1;$p && goto A;$p=0) { A: $ok = 1 }
196 ok($ok, 'weird case of goto and for(;;) loop');
197 is($deprecated, 1, "following goto and for(;;) loop");
201 # bug #9990 - don't prematurely free the CV we're &going to.
205 goto sub { $x=0; ok(1,"don't prematurely free CV\n") }
209 # bug #99850, which is similar - freeing the subroutine we are about to
210 # go(in)to during a FREETMPS call should not crash perl.
214 DESTROY { undef &reftype }
215 eval { sub { my $guard = bless []; goto &reftype }->() };
217 like $@, qr/^Goto undefined subroutine &_99850::reftype at /,
218 'goto &foo undefining &foo on sub cleanup';
220 # When croaking after discovering that the new CV you're about to goto is
221 # undef, make sure that the old CV isn't doubly freed.
226 # creating a new closure here encourages any prematurely freed
227 # CV to be reallocated
228 sub DESTROY { undef &undef_sub; my $x = sub { $count } }
232 my $guard = bless []; # trigger DESTROY during goto
240 ::is($count, 10, "goto undef_sub safe");
243 # make sure that nothing nasty happens if the old CV is freed while
249 no warnings 'redefine';
253 sub g { $results = "(@_)" }
256 ::is($results, "(1 2 3)", "Free_cv");
260 # bug #22181 - this used to coredump or make $x undefined, due to
261 # erroneous popping of the inner BLOCK context
264 for ($count=0; $count<2; $count++) {
270 is($ok, 1, 'goto in for(;;) with continuation');
272 # bug #22299 - goto in require doesn't find label
274 open my $f, ">Op_goto01.pm" or die;
284 $r = runperl(prog => 'BEGIN { unshift @INC, q[.] } use Op_goto01; print qq[DONE\n]');
285 is($r, "OK\nDONE\n", "goto within use-d file");
286 unlink_all "Op_goto01.pm";
288 # test for [perl #24108]
291 sub i_return_a_label {
293 return "returned_label";
295 eval { goto +i_return_a_label; };
299 is($count, 1, 'called i_return_a_label');
300 ok($ok, 'skipped to returned_label');
302 # [perl #29708] - goto &foo could leave foo() at depth two with
303 # @_ == PL_sv_undef, causing a coredump
308 'sub f { return if $d; $d=1; my $a=sub {goto &f}; &$a; f() } f(); print qq(ok\n)',
311 is($r, "ok\n", 'avoid pad without an @_');
314 fail('goto moretests');
319 is(curr_test(), 9, 'eval "goto $x"');
321 # Test autoloading mechanism.
324 my ($pack, $file, $line) = caller; # Should indicate original call stats.
325 is("@_ $pack $file $line", "1 2 3 main $::FILE $::LINE",
326 'autoloading mechanism.');
331 no warnings 'redefine';
332 sub one { pass('sub one'); goto &two; fail('sub one tail'); }
338 $::LINE = __LINE__ + 1;
342 my $wherever = 'NOWHERE';
343 eval { goto $wherever };
344 like($@, qr/Can't find label NOWHERE/, 'goto NOWHERE sets $@');
347 # see if a modified @_ propagates
351 sub DESTROY { my $s = shift; ::is($s->[0], $i, "destroy $i"); }
352 sub show { ::is(+@_, 5, "show $i",); }
353 sub start { push @_, 1, "foo", {}; goto &show; }
354 for (1..3) { $i = $_; start(bless([$_]), 'bar'); }
361 sub AUTOLOAD { $ok = 1 if "@_" eq "foo" }
368 my $wherever = 'FINALE';
371 fail('goto $wherever');
374 # test goto duplicated labels.
380 L4: # not outer scope
387 like($@, qr/Can't "goto" into the middle of a foreach loop/,
388 'catch goto middle of foreach');
391 # ambiguous label resolution (outer scope means endless loop!)
395 is($z, 10, 'prefer same scope (loop body) to outer scope (loop entry)');
399 is($z, 10, 'prefer same scope: second');
407 is($z, 10, 'prefer this scope (block body) to outer scope (block entry)');
411 is($z, 10, 'prefer this scope: second');
418 L3: # not inner scope
422 is($z, 10, 'prefer this scope to inner scope');
426 is($z, 10, 'prefer this scope to inner scope: second');
429 L4: # not outer scope
433 L4: # not inner scope
437 is($z, 1, 'prefer this scope to inner,outer scopes');
441 is($z, 1, 'prefer this scope to inner,outer scopes: second');
447 L2: # without this, fails 1 (middle) out of 3 iterations
452 "same label, multiple times in same scope (choose 1st) $loop");
453 goto L2 if $z == 10 and not $loop++;
458 # This bug was introduced in Aug 2010 by commit ac56e7de46621c6f
459 # Peephole optimise adjacent pairs of nextstate ops.
460 # and fixed in Oct 2014 by commit f5b5c2a37af87535
461 # Simplify double-nextstate optimisation
463 # The bug manifests as a warning
464 # Use of "goto" to jump into a construct is deprecated at t/op/goto.t line 442.
465 # and $out is undefined. Devel::Peek reveals that the lexical in the pad has
466 # been reset to undef. I infer that pp_goto thinks that it's leaving one scope
467 # and entering another, but I don't know *why* it thinks that. Whilst this bug
468 # has been fixed by Father C, because I don't understand why it happened, I am
469 # not confident that other related bugs remain (or have always existed).
481 $out .= 'perl rules';
484 is($out, 'perl rules', '$out has not been erroneously reset to undef');
488 is($deprecated, 0, 'no warning was emmitted');
490 # deep recursion with gotos eventually caused a stack reallocation
491 # which messed up buggy internals that didn't expect the stack to move
495 no warnings 'recursion';
500 $_[0] ? +1 + recurse1($_[0] - 1) : 0
503 $SIG{__WARN__} = sub { ++$w };
504 is(recurse1(500), 500, 'recursive goto &foo');
505 is $w, 0, 'no recursion warnings for "no warnings; goto &sub"';
506 delete $SIG{__WARN__};
508 # [perl #32039] Chained goto &sub drops data too early.
510 sub a32039 { @_=("foo"); goto &b32039; }
511 sub b32039 { goto &c32039; }
512 sub c32039 { is($_[0], 'foo', 'chained &goto') }
515 # [perl #35214] next and redo re-entered the loop with the wrong cop,
516 # causing a subsequent goto to crash
522 'for ($_=0;$_<3;$_++){A: if($_==1){next} if($_==2){$_++;goto A}}print qq(ok\n)'
524 is($r, "ok\n", 'next and goto');
529 'for ($_=0;$_<3;$_++){A: if($_==1){$_++;redo} if($_==2){$_++;goto A}}print qq(ok\n)'
531 is($r, "ok\n", 'redo and goto');
534 # goto &foo not allowed in evals
538 like($@, qr/Can't goto subroutine from an eval-string/, 'eval string');
540 like($@, qr/Can't goto subroutine from an eval-block/, 'eval block');
542 # goto &foo leaves @_ alone when called from a sub
543 sub returnarg { $_[0] };
545 local *_ = ["ick and queasy"];
547 }->("quick and easy"), "ick and queasy",
548 'goto &foo with *_{ARRAY} replaced';
549 my @__ = byte_utf8a_to_utf8n("\xc4\x80");
550 sub { local *_ = \@__; goto &utf8::decode }->("no thinking aloud");
551 is "@__", chr 256, 'goto &xsub with replaced *_{ARRAY}';
553 # And goto &foo should leave reified @_ alone
554 sub { *__ = \@_; goto &null } -> ("rough and tubbery");
555 is ${*__}[0], 'rough and tubbery', 'goto &foo leaves reified @_ alone';
557 # goto &xsub when @_ has nonexistent elements
559 no warnings "uninitialized";
562 & {sub { goto &utf8::encode }};
563 is @_, 1, 'num of elems in @_ after goto &xsub with nonexistent $_[0]';
564 is $_[0], "", 'content of nonexistent $_[0] is modified by goto &xsub';
567 # goto &xsub when @_ itself does not exist
569 eval { & { sub { goto &utf8::encode } } };
570 # The main thing we are testing is that it did not crash. But make sure
571 # *_{ARRAY} was untouched, too.
572 is *_{ARRAY}, undef, 'goto &xsub when @_ does not exist';
574 # goto &perlsub when @_ itself does not exist [perl #119949]
575 # This was only crashing when the replaced sub call had an argument list.
576 # (I.e., &{ sub { goto ... } } did not crash.)
580 is *_{ARRAY}, undef, 'goto &perlsub when @_ does not exist';
586 is *_{ARRAY}, undef, 'goto &sub when @_ does not exist (local *_)';
591 # [perl #36521] goto &foo in warn handler could defeat recursion avoider
596 prog => 'my $d; my $w = sub { return if $d++; warn q(bar)}; local $SIG{__WARN__} = sub { goto &$w; }; warn q(foo);'
598 like($r, qr/bar/, "goto &foo in warn");
602 local $TODO = "[perl #43403] goto() from an if to an else doesn't undo local () changes";
603 our $global = "unmodified";
604 if ($global) { # true but not constant-folded
605 local $global = "modified";
608 ELSE: is($global, "unmodified");
612 is($deprecated, 0, "following TODOed test for #43403");
618 F1:++$x and eval 'return if ++$y == 10; goto F1;';
620 'labels outside evals can be distinguished from the start of the eval');
624 die "You can't get here";
627 ouch_eth: pass('labels persist even if their statement is optimised away');
640 skip_if_miniperl("no dynamic loading on miniperl, so can't load PerlIO::scalar", 1);
642 open(CHOLET, ">", \$cholet);
645 $foo .= "(".$cholet.")";
646 is($foo, "(0)(1)(wellington\n)", "label before format decl");
655 sub alderney { return "tobermory"; }
657 $foo .= "(".alderney().")";
658 is($foo, "(A)(B)(tobermory)", "label before sub decl");
660 $foo = "[0:".__PACKAGE__."]";
667 $foo .= "[1:".__PACKAGE__."]";
668 $foo .= "[2:".__PACKAGE__."]";
670 $foo .= "[3:".__PACKAGE__."]";
671 is($foo, "[0:main][1:Tomsk][2:Tomsk][3:main]", "label before package decl");
673 $foo = "[A:".__PACKAGE__."]";
680 $foo .= "[B:".__PACKAGE__."]";
682 $foo .= "[C:".__PACKAGE__."]";
683 is($foo, "[A:main][B:Cairngorm][C:main]", "label before package block");
692 BEGIN { $obidos = "x"; }
693 $foo .= "{1$obidos}";
694 is($foo, "{0}{1x}", "label before BEGIN block");
696 $foo = "{A:".(1.5+1.5)."}";
703 $foo .= "{B:".(1.5+1.5)."}";
704 is($foo, "{A:3}{B:2}", "label before use decl");
714 is($foo, "<0><1><2>", "first of three stacked labels");
724 is($foo, "<A><B><C>", "second of three stacked labels");
734 is($foo, ",0.,1.,2.", "third of three stacked labels");
736 # [perl #112316] Wrong behavior regarding labels with same prefix
737 sub same_prefix_labels {
743 if ( !$first_time ) {
757 same_prefix_labels(),
758 "perl 112316: goto and labels with the same prefix doesn't get mixed up"
761 eval { my $x = ""; goto $x };
762 like $@, qr/^goto must have label at /, 'goto $x where $x is empty string';
764 like $@, qr/^goto must have label at /, 'goto ""';
766 like $@, qr/^goto must have label at /, 'argless goto';
768 eval { my $x = "\0"; goto $x };
769 like $@, qr/^Can't find label \0 at /, 'goto $x where $x begins with \0';
771 like $@, qr/^Can't find label \0 at /, 'goto "\0"';
773 sub TIESCALAR { bless [pop] }
774 sub FETCH { $_[0][0] }
775 tie my $t, "", sub { "cluck up porridge" };
776 is eval { sub { goto $t }->() }//$@, 'cluck up porridge',
777 'tied arg returning sub ref';
780 local $::TODO = 'RT #45091: goto in CORE::GLOBAL::exit unsupported';
781 fresh_perl_is(<<'EOC', "before\ndie handler\n", {stderr => 1}, 'RT #45091: goto in CORE::GLOBAL::EXIT');
783 *CORE::GLOBAL::exit = sub {
784 goto FASTCGI_NEXT_REQUEST;
788 eval { that_cgi_script() };
789 FASTCGI_NEXT_REQUEST:
793 sub that_cgi_script {
794 local $SIG{__DIE__} = sub { print "die handler\n"; exit; print "exit failed?\n"; };
796 eval { buggy_code() };
810 return $_[1] <=> $_[0];
812 is eval { join(":", sort revnumcmp (9,5,1,3,7)) }, "9:7:5:3:1",
813 "can goto at top level of multicalled sub";
815 # A bit strange, but goingto these constructs should not cause any stack
816 # problems. Let’s test them to make sure that is the case.
817 no warnings 'deprecated';
818 is \sub :lvalue { goto d; ${*{scalar(do { d: \*foo })}} }->(), \$foo,
819 'goto into rv2sv, rv2gv and scalar';
820 is sub { goto e; $#{; do { e: \@_ } } }->(1..7), 6,
822 is sub { goto f; prototype \&{; do { f: sub ($) {} } } }->(), '$',
823 'goto into srefgen, prototype and rv2cv';
824 is sub { goto g; ref do { g: [] } }->(), 'ARRAY',
826 is sub { goto j; defined undef ${; do { j: \(my $foo = "foo") } } }->(),'',
827 'goto into defined and undef';
828 is sub { goto k; study ++${; do { k: \(my $foo = "foo") } } }->(),'1',
829 'goto into study and preincrement';
830 is sub { goto l; ~-!${; do { l: \(my $foo = 0) } }++ }->(),~-1,
831 'goto into complement, not, negation and postincrement';
832 like sub { goto n; sin cos exp log sqrt do { n: 1 } }->(),qr/^0\.51439/,
833 'goto into sin, cos, exp, log, and sqrt';
834 ok sub { goto o; srand do { o: 0 } }->(),
836 cmp_ok sub { goto p; rand do { p: 1 } }->(), '<', 1,
838 is sub { goto r; chr ord length int hex oct abs do { r: -15.5 } }->(), 2,
839 'goto into chr, ord, length, int, hex, oct and abs';
840 is sub { goto t; ucfirst lcfirst uc lc do { t: "q" } }->(), 'Q',
841 'goto into ucfirst, lcfirst, uc and lc';
843 is sub { goto u; \@{; quotemeta do { u: "." } } }->(), \@{'\.'},
844 'goto into rv2av and quotemeta';
846 is join(" ",sub { goto v; %{; do { v: +{1..2} } } }->()), '1 2',
848 is join(" ",sub { goto w; $_ || do { w: "w" } }->()), 'w',
849 'goto into rhs of or';
850 is join(" ",sub { goto x; $_ && do { x: "w" } }->()), 'w',
851 'goto into rhs of and';
852 is join(" ",sub { goto z; $_ ? do { z: "w" } : 0 }->()), 'w',
853 'goto into first leg of ?:';
854 is join(" ",sub { goto z; $_ ? 0 : do { z: "w" } }->()), 'w',
855 'goto into second leg of ?:';
856 is sub { goto z; caller do { z: 0 } }->(), 'main',
858 is sub { goto z; exit do { z: return "foo" } }->(), 'foo',
860 is sub { goto z; eval do { z: "'foo'" } }->(), 'foo',
863 local $TODO = "glob() does not currently return a list on VMS" if $^O eq 'VMS';
864 is join(",",sub { goto z; glob do { z: "foo bar" } }->()), 'foo,bar',
868 # Erroneous inward goto warning, followed by crash.
869 # The eval must be in an assignment.
880 # Goto the *first* parameter of a binary expression, which is harmless.
887 is $@,'', 'goto the first parameter of a binary expression [perl #132854]';
889 # v5.31.3-198-gd2cd363728 broke this. goto &XS_sub wasn't restoring
890 # cx->blk_sub.old_cxsubix. Would panic in pp_return
894 sub g198 { goto &UNIVERSAL::isa }
903 is $@, "", "v5.31.3-198-gd2cd363728";
908 # 'goto &xs_sub' should provide the correct caller context to an XS sub
912 skip "No XS::APItest in miniperl", 6 if is_miniperl();
916 sub f_19188 { goto &XS::APItest::gimme }
917 sub g_19188{ f_19188(); }
921 is ($XS::APItest::GIMME_V, 1, 'xs_goto void (#19188)');
924 is ($XS::APItest::GIMME_V, 2, 'xs_goto scalar (#19188)');
927 is ($XS::APItest::GIMME_V, 3, 'xs_goto list (#19188)');
930 is ($XS::APItest::GIMME_V, 1, 'xs_goto indirect void (#19188)');
933 is ($XS::APItest::GIMME_V, 2, 'xs_goto indirect scalar (#19188)');
936 is ($XS::APItest::GIMME_V, 3, 'xs_goto indirect list (#19188)');
939 # GH #19936 segfault on goto &xs_sub when calling sub is replaced
942 skip "No XS::APItest in miniperl", 2 if is_miniperl();
944 # utf8::is_utf8() is just an example of an XS sub
945 sub foo_19936 { *foo_19936 = {}; goto &utf8::is_utf8 }
946 ok(foo_19936("\x{100}"), "GH #19936 utf8 XS call");
948 # the gimme XS function accesses PL_op, which was null before the fix
949 sub bar_19936 { *bar_19936 = {}; goto &XS::APItest::gimme }
951 is($XS::APItest::GIMME_V, 3, "GH #19936 gimme XS call");