1#!./perl 2 3# "This IS structured code. It's just randomly structured." 4 5BEGIN { 6 chdir 't' if -d 't'; 7 require "./test.pl"; 8 set_up_inc( qw(. ../lib) ); 9 require './charset_tools.pl'; 10} 11 12use warnings; 13use strict; 14use Config; 15plan tests => 134; 16our $TODO; 17 18my $deprecated = 0; 19 20local $SIG{__WARN__} = sub { 21 if ($_[0] =~ m/jump into a construct.*?, and will become fatal in Perl 5\.42/) { 22 $deprecated++; 23 } 24 else { warn $_[0] } 25}; 26 27our $foo; 28while ($?) { 29 $foo = 1; 30 label1: 31 is($deprecated, 1, "following label1"); 32 $deprecated = 0; 33 $foo = 2; 34 goto label2; 35} continue { 36 $foo = 0; 37 goto label4; 38 label3: 39 is($deprecated, 1, "following label3"); 40 $deprecated = 0; 41 $foo = 4; 42 goto label4; 43} 44is($deprecated, 0, "after 'while' loop"); 45goto label1; 46 47$foo = 3; 48 49label2: 50is($foo, 2, 'escape while loop'); 51is($deprecated, 0, "following label2"); 52goto label3; 53 54label4: 55is($foo, 4, 'second escape while loop'); 56 57my $r = run_perl(prog => 'goto foo;', stderr => 1); 58like($r, qr/label/, 'cant find label'); 59 60my $ok = 0; 61sub foo { 62 goto bar; 63 return; 64bar: 65 $ok = 1; 66} 67 68&foo; 69ok($ok, 'goto in sub'); 70 71sub bar { 72 my $x = 'bypass'; 73 eval "goto $x"; 74} 75 76&bar; 77exit; 78 79FINALE: 80is(curr_test(), 20, 'FINALE'); 81 82# does goto LABEL handle block contexts correctly? 83# note that this scope-hopping differs from last & next, 84# which always go up-scope strictly. 85my $count = 0; 86my $cond = 1; 87for (1) { 88 if ($cond == 1) { 89 $cond = 0; 90 goto OTHER; 91 } 92 elsif ($cond == 0) { 93 OTHER: 94 $cond = 2; 95 is($count, 0, 'OTHER'); 96 $count++; 97 goto THIRD; 98 } 99 else { 100 THIRD: 101 is($count, 1, 'THIRD'); 102 $count++; 103 } 104} 105is($count, 2, 'end of loop'); 106 107# Does goto work correctly within a for(;;) loop? 108# (BUG ID 20010309.004 (#5998)) 109 110for(my $i=0;!$i++;) { 111 my $x=1; 112 goto label; 113 label: is($x, 1, 'goto inside a for(;;) loop body from inside the body'); 114} 115 116# Does goto work correctly going *to* a for(;;) loop? 117# (make sure it doesn't skip the initializer) 118 119my ($z, $y) = (0); 120FORL1: for ($y=1; $z;) { 121 ok($y, 'goto a for(;;) loop, from outside (does initializer)'); 122 goto TEST19} 123($y,$z) = (0, 1); 124goto FORL1; 125 126# Even from within the loop? 127TEST19: $z = 0; 128FORL2: for($y=1; 1;) { 129 if ($z) { 130 ok($y, 'goto a for(;;) loop, from inside (does initializer)'); 131 last; 132 } 133 ($y, $z) = (0, 1); 134 goto FORL2; 135} 136 137# Does goto work correctly within a try block? 138# (BUG ID 20000313.004) - [perl #2359] 139$ok = 0; 140eval { 141 my $variable = 1; 142 goto LABEL20; 143 LABEL20: $ok = 1 if $variable; 144}; 145ok($ok, 'works correctly within a try block'); 146is($@, "", '...and $@ not set'); 147 148# And within an eval-string? 149$ok = 0; 150eval q{ 151 my $variable = 1; 152 goto LABEL21; 153 LABEL21: $ok = 1 if $variable; 154}; 155ok($ok, 'works correctly within an eval string'); 156is($@, "", '...and $@ still not set'); 157 158 159# Test that goto works in nested eval-string 160$ok = 0; 161{eval q{ 162 eval q{ 163 goto LABEL22; 164 }; 165 $ok = 0; 166 last; 167 168 LABEL22: $ok = 1; 169}; 170$ok = 0 if $@; 171} 172ok($ok, 'works correctly in a nested eval string'); 173 174{ 175 my $false = 0; 176 my $count; 177 178 $ok = 0; 179 { goto A; A: $ok = 1 } continue { } 180 ok($ok, '#20357 goto inside /{ } continue { }/ loop'); 181 182 $ok = 0; 183 { do { goto A; A: $ok = 1 } while $false } 184 ok($ok, '#20154 goto inside /do { } while ()/ loop'); 185 $ok = 0; 186 foreach(1) { goto A; A: $ok = 1 } continue { }; 187 ok($ok, 'goto inside /foreach () { } continue { }/ loop'); 188 189 $ok = 0; 190 sub a { 191 A: { if ($false) { redo A; B: $ok = 1; redo A; } } 192 goto B unless $count++; 193 } 194 is($deprecated, 0, "before calling sub a()"); 195 a(); 196 ok($ok, '#19061 loop label wiped away by goto'); 197 is($deprecated, 1, "after calling sub a()"); 198 $deprecated = 0; 199 200 $ok = 0; 201 my $p; 202 for ($p=1;$p && goto A;$p=0) { A: $ok = 1 } 203 ok($ok, 'weird case of goto and for(;;) loop'); 204 is($deprecated, 1, "following goto and for(;;) loop"); 205 $deprecated = 0; 206} 207 208# bug #9990 - don't prematurely free the CV we're &going to. 209 210sub f1 { 211 my $x; 212 goto sub { $x=0; ok(1,"don't prematurely free CV\n") } 213} 214f1(); 215 216# bug #99850, which is similar - freeing the subroutine we are about to 217# go(in)to during a FREETMPS call should not crash perl. 218 219package _99850 { 220 sub reftype{} 221 DESTROY { undef &reftype } 222 eval { sub { my $guard = bless []; goto &reftype }->() }; 223} 224like $@, qr/^Goto undefined subroutine &_99850::reftype at /, 225 'goto &foo undefining &foo on sub cleanup'; 226 227# When croaking after discovering that the new CV you're about to goto is 228# undef, make sure that the old CV isn't doubly freed. 229 230package Do_undef { 231 my $count; 232 233 # creating a new closure here encourages any prematurely freed 234 # CV to be reallocated 235 sub DESTROY { undef &undef_sub; my $x = sub { $count } } 236 237 sub f { 238 $count++; 239 my $guard = bless []; # trigger DESTROY during goto 240 *undef_sub = sub {}; 241 goto &undef_sub 242 } 243 244 for (1..10) { 245 eval { f() }; 246 } 247 ::is($count, 10, "goto undef_sub safe"); 248} 249 250# make sure that nothing nasty happens if the old CV is freed while 251# goto'ing 252 253package Free_cv { 254 my $results; 255 sub f { 256 no warnings 'redefine'; 257 *f = sub {}; 258 goto &g; 259 } 260 sub g { $results = "(@_)" } 261 262 f(1,2,3); 263 ::is($results, "(1 2 3)", "Free_cv"); 264} 265 266 267# bug #22181 - this used to coredump or make $x undefined, due to 268# erroneous popping of the inner BLOCK context 269 270undef $ok; 271for ($count=0; $count<2; $count++) { 272 my $x = 1; 273 goto LABEL29; 274 LABEL29: 275 $ok = $x; 276} 277is($ok, 1, 'goto in for(;;) with continuation'); 278 279# bug #22299 - goto in require doesn't find label 280 281open my $f, ">Op_goto01.pm" or die; 282print $f <<'EOT'; 283package goto01; 284goto YYY; 285die; 286YYY: print "OK\n"; 2871; 288EOT 289close $f; 290 291$r = runperl(prog => 'BEGIN { unshift @INC, q[.] } use Op_goto01; print qq[DONE\n]'); 292is($r, "OK\nDONE\n", "goto within use-d file"); 293unlink_all "Op_goto01.pm"; 294 295# test for [perl #24108] 296$ok = 1; 297$count = 0; 298sub i_return_a_label { 299 $count++; 300 return "returned_label"; 301} 302eval { goto +i_return_a_label; }; 303$ok = 0; 304 305returned_label: 306is($count, 1, 'called i_return_a_label'); 307ok($ok, 'skipped to returned_label'); 308 309# [perl #29708] - goto &foo could leave foo() at depth two with 310# @_ == PL_sv_undef, causing a coredump 311 312 313$r = runperl( 314 prog => 315 'sub f { return if $d; $d=1; my $a=sub {goto &f}; &$a; f() } f(); print qq(ok\n)', 316 stderr => 1 317 ); 318is($r, "ok\n", 'avoid pad without an @_'); 319 320goto moretests; 321fail('goto moretests'); 322exit; 323 324bypass: 325 326is(curr_test(), 9, 'eval "goto $x"'); 327 328# Test autoloading mechanism. 329 330sub two { 331 my ($pack, $file, $line) = caller; # Should indicate original call stats. 332 is("@_ $pack $file $line", "1 2 3 main $::FILE $::LINE", 333 'autoloading mechanism.'); 334} 335 336sub one { 337 eval <<'END'; 338 no warnings 'redefine'; 339 sub one { pass('sub one'); goto &two; fail('sub one tail'); } 340END 341 goto &one; 342} 343 344$::FILE = __FILE__; 345$::LINE = __LINE__ + 1; 346&one(1,2,3); 347 348{ 349 my $wherever = 'NOWHERE'; 350 eval { goto $wherever }; 351 like($@, qr/Can't find label NOWHERE/, 'goto NOWHERE sets $@'); 352} 353 354# see if a modified @_ propagates 355{ 356 my $i; 357 package Foo; 358 sub DESTROY { my $s = shift; ::is($s->[0], $i, "destroy $i"); } 359 sub show { ::is(+@_, 5, "show $i",); } 360 sub start { push @_, 1, "foo", {}; goto &show; } 361 for (1..3) { $i = $_; start(bless([$_]), 'bar'); } 362} 363 364sub auto { 365 goto &loadit; 366} 367 368sub AUTOLOAD { $ok = 1 if "@_" eq "foo" } 369 370$ok = 0; 371auto("foo"); 372ok($ok, 'autoload'); 373 374{ 375 my $wherever = 'FINALE'; 376 goto $wherever; 377} 378fail('goto $wherever'); 379 380moretests: 381# test goto duplicated labels. 382{ 383 my $z = 0; 384 eval { 385 $z = 0; 386 for (0..1) { 387 L4: # not outer scope 388 $z += 10; 389 last; 390 } 391 goto L4 if $z == 10; 392 last; 393 }; 394 like($@, qr/Can't "goto" into the middle of a foreach loop/, 395 'catch goto middle of foreach'); 396 397 $z = 0; 398 # ambiguous label resolution (outer scope means endless loop!) 399 L1: 400 for my $x (0..1) { 401 $z += 10; 402 is($z, 10, 'prefer same scope (loop body) to outer scope (loop entry)'); 403 goto L1 unless $x; 404 $z += 10; 405 L1: 406 is($z, 10, 'prefer same scope: second'); 407 last; 408 } 409 410 $z = 0; 411 L2: 412 { 413 $z += 10; 414 is($z, 10, 'prefer this scope (block body) to outer scope (block entry)'); 415 goto L2 if $z == 10; 416 $z += 10; 417 L2: 418 is($z, 10, 'prefer this scope: second'); 419 } 420 421 422 { 423 $z = 0; 424 while (1) { 425 L3: # not inner scope 426 $z += 10; 427 last; 428 } 429 is($z, 10, 'prefer this scope to inner scope'); 430 goto L3 if $z == 10; 431 $z += 10; 432 L3: # this scope ! 433 is($z, 10, 'prefer this scope to inner scope: second'); 434 } 435 436 L4: # not outer scope 437 { 438 $z = 0; 439 while (1) { 440 L4: # not inner scope 441 $z += 1; 442 last; 443 } 444 is($z, 1, 'prefer this scope to inner,outer scopes'); 445 goto L4 if $z == 1; 446 $z += 10; 447 L4: # this scope ! 448 is($z, 1, 'prefer this scope to inner,outer scopes: second'); 449 } 450 451 { 452 my $loop = 0; 453 for my $x (0..1) { 454 L2: # without this, fails 1 (middle) out of 3 iterations 455 $z = 0; 456 L2: 457 $z += 10; 458 is($z, 10, 459 "same label, multiple times in same scope (choose 1st) $loop"); 460 goto L2 if $z == 10 and not $loop++; 461 } 462 } 463} 464 465# This bug was introduced in Aug 2010 by commit ac56e7de46621c6f 466# Peephole optimise adjacent pairs of nextstate ops. 467# and fixed in Oct 2014 by commit f5b5c2a37af87535 468# Simplify double-nextstate optimisation 469 470# The bug manifests as a warning 471# Use of "goto" to jump into a construct is deprecated at t/op/goto.t line 442. 472# and $out is undefined. Devel::Peek reveals that the lexical in the pad has 473# been reset to undef. I infer that pp_goto thinks that it's leaving one scope 474# and entering another, but I don't know *why* it thinks that. Whilst this bug 475# has been fixed by Father C, because I don't understand why it happened, I am 476# not confident that other related bugs remain (or have always existed). 477 478sub DEBUG_TIME() { 479 0; 480} 481 482{ 483 if (DEBUG_TIME) { 484 } 485 486 { 487 my $out = ""; 488 $out .= 'perl rules'; 489 goto no_list; 490 no_list: 491 is($out, 'perl rules', '$out has not been erroneously reset to undef'); 492 }; 493} 494 495is($deprecated, 0, 'no warning was emmitted'); 496 497# deep recursion with gotos eventually caused a stack reallocation 498# which messed up buggy internals that didn't expect the stack to move 499 500sub recurse1 { 501 unshift @_, "x"; 502 no warnings 'recursion'; 503 goto &recurse2; 504} 505sub recurse2 { 506 my $x = shift; 507 $_[0] ? +1 + recurse1($_[0] - 1) : 0 508} 509my $w = 0; 510$SIG{__WARN__} = sub { ++$w }; 511is(recurse1(500), 500, 'recursive goto &foo'); 512is $w, 0, 'no recursion warnings for "no warnings; goto &sub"'; 513delete $SIG{__WARN__}; 514 515# [perl #32039] Chained goto &sub drops data too early. 516 517sub a32039 { @_=("foo"); goto &b32039; } 518sub b32039 { goto &c32039; } 519sub c32039 { is($_[0], 'foo', 'chained &goto') } 520a32039(); 521 522# [perl #35214] next and redo re-entered the loop with the wrong cop, 523# causing a subsequent goto to crash 524 525{ 526 my $r = runperl( 527 stderr => 1, 528 prog => 529'for ($_=0;$_<3;$_++){A: if($_==1){next} if($_==2){$_++;goto A}}print qq(ok\n)' 530 ); 531 is($r, "ok\n", 'next and goto'); 532 533 $r = runperl( 534 stderr => 1, 535 prog => 536'for ($_=0;$_<3;$_++){A: if($_==1){$_++;redo} if($_==2){$_++;goto A}}print qq(ok\n)' 537 ); 538 is($r, "ok\n", 'redo and goto'); 539} 540 541# goto &foo not allowed in evals 542 543sub null { 1 }; 544eval 'goto &null'; 545like($@, qr/Can't goto subroutine from an eval-string/, 'eval string'); 546eval { goto &null }; 547like($@, qr/Can't goto subroutine from an eval-block/, 'eval block'); 548 549# goto &foo leaves @_ alone when called from a sub 550sub returnarg { $_[0] }; 551is sub { 552 local *_ = ["ick and queasy"]; 553 goto &returnarg; 554}->("quick and easy"), "ick and queasy", 555 'goto &foo with *_{ARRAY} replaced'; 556my @__ = byte_utf8a_to_utf8n("\xc4\x80"); 557sub { local *_ = \@__; goto &utf8::decode }->("no thinking aloud"); 558is "@__", chr 256, 'goto &xsub with replaced *_{ARRAY}'; 559 560# And goto &foo should leave reified @_ alone 561sub { *__ = \@_; goto &null } -> ("rough and tubbery"); 562is ${*__}[0], 'rough and tubbery', 'goto &foo leaves reified @_ alone'; 563 564# goto &xsub when @_ has nonexistent elements 565{ 566 no warnings "uninitialized"; 567 local @_ = (); 568 $#_++; 569 & {sub { goto &utf8::encode }}; 570 is @_, 1, 'num of elems in @_ after goto &xsub with nonexistent $_[0]'; 571 is $_[0], "", 'content of nonexistent $_[0] is modified by goto &xsub'; 572} 573 574# goto &xsub when @_ itself does not exist 575undef *_; 576eval { & { sub { goto &utf8::encode } } }; 577# The main thing we are testing is that it did not crash. But make sure 578# *_{ARRAY} was untouched, too. 579is *_{ARRAY}, undef, 'goto &xsub when @_ does not exist'; 580 581# goto &perlsub when @_ itself does not exist [perl #119949] 582# This was only crashing when the replaced sub call had an argument list. 583# (I.e., &{ sub { goto ... } } did not crash.) 584sub { 585 undef *_; 586 goto sub { 587 is *_{ARRAY}, undef, 'goto &perlsub when @_ does not exist'; 588 } 589}->(); 590sub { 591 local *_; 592 goto sub { 593 is *_{ARRAY}, undef, 'goto &sub when @_ does not exist (local *_)'; 594 } 595}->(); 596 597 598# [perl #36521] goto &foo in warn handler could defeat recursion avoider 599 600{ 601 my $r = runperl( 602 stderr => 1, 603 prog => 'my $d; my $w = sub { return if $d++; warn q(bar)}; local $SIG{__WARN__} = sub { goto &$w; }; warn q(foo);' 604 ); 605 like($r, qr/bar/, "goto &foo in warn"); 606} 607 608TODO: { 609 local $TODO = "[perl #43403] goto() from an if to an else doesn't undo local () changes"; 610 our $global = "unmodified"; 611 if ($global) { # true but not constant-folded 612 local $global = "modified"; 613 goto ELSE; 614 } else { 615 ELSE: is($global, "unmodified"); 616 } 617} 618 619is($deprecated, 0, "following TODOed test for #43403"); 620 621#74290 622{ 623 my $x; 624 my $y; 625 F1:++$x and eval 'return if ++$y == 10; goto F1;'; 626 is($x, 10, 627 'labels outside evals can be distinguished from the start of the eval'); 628} 629 630goto wham_eth; 631die "You can't get here"; 632 633wham_eth: 1 if 0; 634ouch_eth: pass('labels persist even if their statement is optimised away'); 635 636$foo = "(0)"; 637if($foo eq $foo) { 638 goto bungo; 639} 640$foo .= "(9)"; 641bungo: 642format CHOLET = 643wellington 644. 645$foo .= "(1)"; 646{ 647 my $cholet; 648 open(CHOLET, ">", \$cholet); 649 write CHOLET; 650 close CHOLET; 651 $foo .= "(".$cholet.")"; 652 is($foo, "(0)(1)(wellington\n)", "label before format decl"); 653} 654 655$foo = "(A)"; 656if($foo eq $foo) { 657 goto orinoco; 658} 659$foo .= "(X)"; 660orinoco: 661sub alderney { return "tobermory"; } 662$foo .= "(B)"; 663$foo .= "(".alderney().")"; 664is($foo, "(A)(B)(tobermory)", "label before sub decl"); 665 666$foo = "[0:".__PACKAGE__."]"; 667if($foo eq $foo) { 668 goto bulgaria; 669} 670$foo .= "[9]"; 671bulgaria: 672package Tomsk; 673$foo .= "[1:".__PACKAGE__."]"; 674$foo .= "[2:".__PACKAGE__."]"; 675package main; 676$foo .= "[3:".__PACKAGE__."]"; 677is($foo, "[0:main][1:Tomsk][2:Tomsk][3:main]", "label before package decl"); 678 679$foo = "[A:".__PACKAGE__."]"; 680if($foo eq $foo) { 681 goto adelaide; 682} 683$foo .= "[Z]"; 684adelaide: 685package Cairngorm { 686 $foo .= "[B:".__PACKAGE__."]"; 687} 688$foo .= "[C:".__PACKAGE__."]"; 689is($foo, "[A:main][B:Cairngorm][C:main]", "label before package block"); 690 691our $obidos; 692$foo = "{0}"; 693if($foo eq $foo) { 694 goto shansi; 695} 696$foo .= "{9}"; 697shansi: 698BEGIN { $obidos = "x"; } 699$foo .= "{1$obidos}"; 700is($foo, "{0}{1x}", "label before BEGIN block"); 701 702$foo = "{A:".(1.5+1.5)."}"; 703if($foo eq $foo) { 704 goto stepney; 705} 706$foo .= "{Z}"; 707stepney: 708use integer; 709$foo .= "{B:".(1.5+1.5)."}"; 710is($foo, "{A:3}{B:2}", "label before use decl"); 711 712$foo = "<0>"; 713if($foo eq $foo) { 714 goto tom; 715} 716$foo .= "<9>"; 717tom: dick: harry: 718$foo .= "<1>"; 719$foo .= "<2>"; 720is($foo, "<0><1><2>", "first of three stacked labels"); 721 722$foo = "<A>"; 723if($foo eq $foo) { 724 goto beta; 725} 726$foo .= "<Z>"; 727alpha: beta: gamma: 728$foo .= "<B>"; 729$foo .= "<C>"; 730is($foo, "<A><B><C>", "second of three stacked labels"); 731 732$foo = ",0."; 733if($foo eq $foo) { 734 goto gimel; 735} 736$foo .= ",9."; 737alef: bet: gimel: 738$foo .= ",1."; 739$foo .= ",2."; 740is($foo, ",0.,1.,2.", "third of three stacked labels"); 741 742# [perl #112316] Wrong behavior regarding labels with same prefix 743sub same_prefix_labels { 744 my $pass; 745 my $first_time = 1; 746 CATCH: { 747 if ( $first_time ) { 748 CATCHLOOP: { 749 if ( !$first_time ) { 750 return 0; 751 } 752 $first_time--; 753 goto CATCH; 754 } 755 } 756 else { 757 return 1; 758 } 759 } 760} 761 762ok( 763 same_prefix_labels(), 764 "perl 112316: goto and labels with the same prefix doesn't get mixed up" 765); 766 767eval { my $x = ""; goto $x }; 768like $@, qr/^goto must have label at /, 'goto $x where $x is empty string'; 769eval { goto "" }; 770like $@, qr/^goto must have label at /, 'goto ""'; 771eval { goto }; 772like $@, qr/^goto must have label at /, 'argless goto'; 773 774eval { my $x = "\0"; goto $x }; 775like $@, qr/^Can't find label \0 at /, 'goto $x where $x begins with \0'; 776eval { goto "\0" }; 777like $@, qr/^Can't find label \0 at /, 'goto "\0"'; 778 779sub TIESCALAR { bless [pop] } 780sub FETCH { $_[0][0] } 781tie my $t, "", sub { "cluck up porridge" }; 782is eval { sub { goto $t }->() }//$@, 'cluck up porridge', 783 'tied arg returning sub ref'; 784 785TODO: { 786 local $::TODO = 'RT #45091: goto in CORE::GLOBAL::exit unsupported'; 787 fresh_perl_is(<<'EOC', "before\ndie handler\n", {stderr => 1}, 'RT #45091: goto in CORE::GLOBAL::EXIT'); 788 BEGIN { 789 *CORE::GLOBAL::exit = sub { 790 goto FASTCGI_NEXT_REQUEST; 791 }; 792 } 793 while (1) { 794 eval { that_cgi_script() }; 795 FASTCGI_NEXT_REQUEST: 796 last; 797 } 798 799 sub that_cgi_script { 800 local $SIG{__DIE__} = sub { print "die handler\n"; exit; print "exit failed?\n"; }; 801 print "before\n"; 802 eval { buggy_code() }; 803 print "after\n"; 804 } 805 sub buggy_code { 806 die "error!"; 807 print "after die\n"; 808 } 809EOC 810} 811 812sub revnumcmp ($$) { 813 goto FOO; 814 die; 815 FOO: 816 return $_[1] <=> $_[0]; 817} 818is eval { join(":", sort revnumcmp (9,5,1,3,7)) }, "9:7:5:3:1", 819 "can goto at top level of multicalled sub"; 820 821# A bit strange, but goingto these constructs should not cause any stack 822# problems. Let’s test them to make sure that is the case. 823no warnings 'deprecated'; 824is \sub :lvalue { goto d; ${*{scalar(do { d: \*foo })}} }->(), \$foo, 825 'goto into rv2sv, rv2gv and scalar'; 826is sub { goto e; $#{; do { e: \@_ } } }->(1..7), 6, 827 'goto into $#{...}'; 828is sub { goto f; prototype \&{; do { f: sub ($) {} } } }->(), '$', 829 'goto into srefgen, prototype and rv2cv'; 830is sub { goto g; ref do { g: [] } }->(), 'ARRAY', 831 'goto into ref'; 832is sub { goto j; defined undef ${; do { j: \(my $foo = "foo") } } }->(),'', 833 'goto into defined and undef'; 834is sub { goto k; study ++${; do { k: \(my $foo = "foo") } } }->(),'1', 835 'goto into study and preincrement'; 836is sub { goto l; ~-!${; do { l: \(my $foo = 0) } }++ }->(),~-1, 837 'goto into complement, not, negation and postincrement'; 838like sub { goto n; sin cos exp log sqrt do { n: 1 } }->(),qr/^0\.51439/, 839 'goto into sin, cos, exp, log, and sqrt'; 840ok sub { goto o; srand do { o: 0 } }->(), 841 'goto into srand'; 842cmp_ok sub { goto p; rand do { p: 1 } }->(), '<', 1, 843 'goto into rand'; 844is sub { goto r; chr ord length int hex oct abs do { r: -15.5 } }->(), 2, 845 'goto into chr, ord, length, int, hex, oct and abs'; 846is sub { goto t; ucfirst lcfirst uc lc do { t: "q" } }->(), 'Q', 847 'goto into ucfirst, lcfirst, uc and lc'; 848{ no strict; 849 is sub { goto u; \@{; quotemeta do { u: "." } } }->(), \@{'\.'}, 850 'goto into rv2av and quotemeta'; 851} 852is join(" ",sub { goto v; %{; do { v: +{1..2} } } }->()), '1 2', 853 'goto into rv2hv'; 854is join(" ",sub { goto w; $_ || do { w: "w" } }->()), 'w', 855 'goto into rhs of or'; 856is join(" ",sub { goto x; $_ && do { x: "w" } }->()), 'w', 857 'goto into rhs of and'; 858is join(" ",sub { goto z; $_ ? do { z: "w" } : 0 }->()), 'w', 859 'goto into first leg of ?:'; 860is join(" ",sub { goto z; $_ ? 0 : do { z: "w" } }->()), 'w', 861 'goto into second leg of ?:'; 862is sub { goto z; caller do { z: 0 } }->(), 'main', 863 'goto into caller'; 864is sub { goto z; exit do { z: return "foo" } }->(), 'foo', 865 'goto into exit'; 866is sub { goto z; eval do { z: "'foo'" } }->(), 'foo', 867 'goto into eval'; 868TODO: { 869 local $TODO = "glob() does not currently return a list on VMS" if $^O eq 'VMS'; 870 is join(",",sub { goto z; glob do { z: "foo bar" } }->()), 'foo,bar', 871 'goto into glob'; 872} 873# [perl #132799] 874# Erroneous inward goto warning, followed by crash. 875# The eval must be in an assignment. 876sub _routine { 877 my $e = eval { 878 goto L2; 879 L2: 880 } 881} 882_routine(); 883pass("bug 132799"); 884 885# [perl #132854] 886# Goto the *first* parameter of a binary expression, which is harmless. 887eval { 888 goto __GEN_2; 889 my $sent = do { 890 __GEN_2: 891 }; 892}; 893is $@,'', 'goto the first parameter of a binary expression [perl #132854]'; 894 895# v5.31.3-198-gd2cd363728 broke this. goto &XS_sub wasn't restoring 896# cx->blk_sub.old_cxsubix. Would panic in pp_return 897 898{ 899 # isa is an XS sub 900 sub g198 { goto &UNIVERSAL::isa } 901 902 sub f198 { 903 g198([], 1 ); 904 { 905 return 1; 906 } 907 } 908 eval { f198(); }; 909 is $@, "", "v5.31.3-198-gd2cd363728"; 910} 911 912# GH #19188 913# 914# 'goto &xs_sub' should provide the correct caller context to an XS sub 915 916SKIP: 917{ 918 skip "No XS::APItest in miniperl", 6 if is_miniperl(); 919 skip "No XS::APItest in static perl", 6 if not $Config{usedl}; 920 921 require XS::APItest; 922 923 sub f_19188 { goto &XS::APItest::gimme } 924 sub g_19188{ f_19188(); } 925 my ($s, @a); 926 927 f_19188(); 928 is ($XS::APItest::GIMME_V, 1, 'xs_goto void (#19188)'); 929 930 $s = f_19188(); 931 is ($XS::APItest::GIMME_V, 2, 'xs_goto scalar (#19188)'); 932 933 @a = f_19188(); 934 is ($XS::APItest::GIMME_V, 3, 'xs_goto list (#19188)'); 935 936 g_19188(); 937 is ($XS::APItest::GIMME_V, 1, 'xs_goto indirect void (#19188)'); 938 939 $s = g_19188(); 940 is ($XS::APItest::GIMME_V, 2, 'xs_goto indirect scalar (#19188)'); 941 942 @a = g_19188(); 943 is ($XS::APItest::GIMME_V, 3, 'xs_goto indirect list (#19188)'); 944} 945 946# GH #19936 segfault on goto &xs_sub when calling sub is replaced 947SKIP: 948{ 949 skip "No XS::APItest in miniperl", 2 if is_miniperl(); 950 skip "No XS::APItest in static perl", 2 if not $Config{usedl}; 951 952 # utf8::is_utf8() is just an example of an XS sub 953 sub foo_19936 { *foo_19936 = {}; goto &utf8::is_utf8 } 954 ok(foo_19936("\x{100}"), "GH #19936 utf8 XS call"); 955 956 # the gimme XS function accesses PL_op, which was null before the fix 957 sub bar_19936 { *bar_19936 = {}; goto &XS::APItest::gimme } 958 my @a = bar_19936(); 959 is($XS::APItest::GIMME_V, 3, "GH #19936 gimme XS call"); 960} 961 962# goto &sub could leave AvARRAY() slots of @_ uninitialised. 963 964{ 965 my $i = 0; 966 my $f = sub { 967 goto &{ sub {} } unless $i++; 968 $_[1] = 1; # create a hole 969 # accessing $_[0] is more for valgrind/ASAN to chew on rather than 970 # we're too concerned about its value. Or it might give "bizarre 971 # copy" errors. 972 is($_[0], undef, "goto and AvARRAY"); 973 }; 974 975 # first call does goto, which gives &$f a fresh AV in pad[0], 976 # which formerly allocated an AvARRAY for it, but didn't zero it 977 $f->(); 978 # second call creates hole in @_ which used to to be a wild SV pointer 979 $f->(); 980} 981