xref: /openbsd-src/gnu/usr.bin/perl/t/comp/form_scope.t (revision b8851fcc53cbe24fd20b090f26dd149e353f6174)
1b39c5158Smillert#!./perl
2898184e3Ssthen
391f110e0Safresh1print "1..14\n";
4898184e3Ssthen
5b39c5158Smillert# Tests bug #22977.  Test case from Dave Mitchell.
6b39c5158Smillertsub f ($);
7b39c5158Smillertsub f ($) {
8b39c5158Smillertmy $test = $_[0];
9b39c5158Smillertwrite;
10b39c5158Smillertformat STDOUT =
11b39c5158Smillertok @<<<<<<<
12b39c5158Smillert$test
13b39c5158Smillert.
14b39c5158Smillert}
15b39c5158Smillert
16b39c5158Smillertf(1);
17b39c5158Smillertf(2);
18898184e3Ssthen
19898184e3Ssthen# A bug caused by the fix for #22977/50528
20898184e3Ssthensub foo {
21898184e3Ssthen  sub bar {
22898184e3Ssthen    # Fill the pad with alphabet soup, to give the closed-over variable a
23898184e3Ssthen    # high padoffset (more likely to trigger the bug and crash).
24898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
25898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
26898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
27898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
28898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
29898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
30898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
31898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
32898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
33898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
34898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
35898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
36898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
37898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
38898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
39898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
40898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
41898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
42898184e3Ssthen    my $x;
43898184e3Ssthen    format STDOUT2 =
44898184e3Ssthen@<<<<<<
45898184e3Ssthen"ok 3".$x # $x is not available, but this should not crash
46898184e3Ssthen.
47898184e3Ssthen  }
48898184e3Ssthen}
49898184e3Ssthen*STDOUT = *STDOUT2{FORMAT};
50898184e3Ssthenundef *bar;
51898184e3Ssthenwrite;
52898184e3Ssthen
53898184e3Ssthen# A regression introduced in 5.10; format cloning would close over the
54898184e3Ssthen# variables in the currently-running sub (the main CV in this test) if the
55898184e3Ssthen# outer sub were an inactive closure.
56898184e3Ssthensub baz {
57898184e3Ssthen  my $a;
58898184e3Ssthen  sub {
59898184e3Ssthen    $a;
60898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t)}
61898184e3Ssthen    my $x;
62898184e3Ssthen    format STDOUT3 =
63898184e3Ssthen@<<<<<<<<<<<<<<<<<<<<<<<<<
64898184e3Ssthendefined $x ? "not ok 4 - $x" : "ok 4"
65898184e3Ssthen.
66898184e3Ssthen  }
67898184e3Ssthen}
68898184e3Ssthen*STDOUT = *STDOUT3{FORMAT};
69898184e3Ssthen{
70898184e3Ssthen  local $^W = 1;
71898184e3Ssthen  my $w;
72898184e3Ssthen  local $SIG{__WARN__} = sub { $w = shift };
73898184e3Ssthen  write;
74898184e3Ssthen  print "not " unless $w =~ /^Variable "\$x" is not available at/;
75898184e3Ssthen  print "ok 5 - closure var not available when outer sub is inactive\n";
76898184e3Ssthen}
77898184e3Ssthen
7891f110e0Safresh1# Formats inside closures should close over the topmost clone of the outer
7991f110e0Safresh1# sub on the call stack.
8091f110e0Safresh1# Tests will be out of sequence if the wrong sub is used.
8191f110e0Safresh1sub make_closure {
8291f110e0Safresh1  my $arg = shift;
8391f110e0Safresh1  sub {
8491f110e0Safresh1    shift == 0 and &$next(1), return;
8591f110e0Safresh1    my $x = "ok $arg";
8691f110e0Safresh1    format STDOUT4 =
8791f110e0Safresh1@<<<<<<<
8891f110e0Safresh1$x
8991f110e0Safresh1.
9091f110e0Safresh1    sub { write }->(); # separate sub, so as not to rely on it being the
9191f110e0Safresh1  }                    # currently-running sub
9291f110e0Safresh1}
9391f110e0Safresh1*STDOUT = *STDOUT4{FORMAT};
9491f110e0Safresh1$clo1 = make_closure 6;
9591f110e0Safresh1$clo2 = make_closure 7;
9691f110e0Safresh1$next = $clo1;
9791f110e0Safresh1&$clo2(0);
9891f110e0Safresh1$next = $clo2;
9991f110e0Safresh1&$clo1(0);
10091f110e0Safresh1
101898184e3Ssthen# Cloning a format whose outside has been undefined
102898184e3Ssthensub x {
103898184e3Ssthen    {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}
104898184e3Ssthen    my $z;
105898184e3Ssthen    format STDOUT6 =
106898184e3Ssthen@<<<<<<<<<<<<<<<<<<<<<<<<<
10791f110e0Safresh1defined $z ? "not ok 8 - $z" : "ok 8"
108898184e3Ssthen.
109898184e3Ssthen}
110898184e3Ssthenundef &x;
111898184e3Ssthen*STDOUT = *STDOUT6{FORMAT};
112898184e3Ssthen{
113898184e3Ssthen  local $^W = 1;
114898184e3Ssthen  my $w;
115898184e3Ssthen  local $SIG{__WARN__} = sub { $w = shift };
116898184e3Ssthen  write;
117898184e3Ssthen  print "not " unless $w =~ /^Variable "\$z" is not available at/;
11891f110e0Safresh1  print "ok 9 - closure var not available when outer sub is undefined\n";
11991f110e0Safresh1}
12091f110e0Safresh1
12191f110e0Safresh1format STDOUT7 =
12291f110e0Safresh1@<<<<<<<<<<<<<<<<<<<<<<<<<<<
12391f110e0Safresh1do { my $x = "ok 10 - closure inside format"; sub { $x }->() }
12491f110e0Safresh1.
12591f110e0Safresh1*STDOUT = *STDOUT7{FORMAT};
12691f110e0Safresh1write;
12791f110e0Safresh1
12891f110e0Safresh1$testn = 12;
12991f110e0Safresh1format STDOUT8 =
13091f110e0Safresh1@<<<< - recursive formats
13191f110e0Safresh1do { my $t = "ok " . $testn--; write if $t =~ 12; $t}
13291f110e0Safresh1.
13391f110e0Safresh1*STDOUT = *STDOUT8{FORMAT};
13491f110e0Safresh1write;
13591f110e0Safresh1
13691f110e0Safresh1sub _13 {
13791f110e0Safresh1    my $x;
13891f110e0Safresh1format STDOUT13 =
139*b8851fccSafresh1@* - formats closing over redefined subs (got @*)
140*b8851fccSafresh1ref \$x eq 'SCALAR' ? "ok 13" : "not ok 13", ref \$x;
14191f110e0Safresh1.
14291f110e0Safresh1}
14391f110e0Safresh1undef &_13;
14491f110e0Safresh1eval 'sub _13 { my @x; write }';
14591f110e0Safresh1*STDOUT = *STDOUT13{FORMAT};
14691f110e0Safresh1_13();
14791f110e0Safresh1
14891f110e0Safresh1# This is a variation of bug #22977, which crashes or fails an assertion
14991f110e0Safresh1# up to 5.16.
15091f110e0Safresh1# Keep this test last if you want test numbers to be sane.
15191f110e0Safresh1BEGIN { \&END }
15291f110e0Safresh1END {
15391f110e0Safresh1  my $test = "ok 14";
15491f110e0Safresh1  *STDOUT = *STDOUT5{FORMAT};
15591f110e0Safresh1  write;
15691f110e0Safresh1  format STDOUT5 =
15791f110e0Safresh1@<<<<<<<
15891f110e0Safresh1$test
15991f110e0Safresh1.
160898184e3Ssthen}
161