1#!./perl -w 2 3BEGIN { 4 chdir 't' if -d 't'; 5 require './test.pl'; 6 set_up_inc('../lib'); 7} 8 9plan(tests => 62); 10 11sub empty_sub {} 12 13is(empty_sub,undef,"Is empty"); 14is(empty_sub(1,2,3),undef,"Is still empty"); 15@test = empty_sub(); 16is(scalar(@test), 0, 'Didnt return anything'); 17@test = empty_sub(1,2,3); 18is(scalar(@test), 0, 'Didnt return anything'); 19 20# [perl #91844] return should always copy 21{ 22 $foo{bar} = 7; 23 for my $x ($foo{bar}) { 24 # Pity test.pl doesnt have isn't. 25 isnt \sub { delete $foo{bar} }->(), \$x, 26 'result of delete(helem) is copied when returned'; 27 } 28 $foo{bar} = 7; 29 for my $x ($foo{bar}) { 30 isnt \sub { return delete $foo{bar} }->(), \$x, 31 'result of delete(helem) is copied when explicitly returned'; 32 } 33 my $x; 34 isnt \sub { delete $_[0] }->($x), \$x, 35 'result of delete(aelem) is copied when returned'; 36 isnt \sub { return delete $_[0] }->($x), \$x, 37 'result of delete(aelem) is copied when explicitly returned'; 38 isnt \sub { ()=\@_; shift }->($x), \$x, 39 'result of shift is copied when returned'; 40 isnt \sub { ()=\@_; return shift }->($x), \$x, 41 'result of shift is copied when explicitly returned'; 42 43 $foo{bar} = 7; 44 my $r = \$foo{bar}; 45 sub { 46 $$r++; 47 isnt($_[0], $$r, "result of delete(helem) is copied: practical test"); 48 }->(sub { delete $foo{bar} }->()); 49} 50 51fresh_perl_is 52 <<'end', "main::foo\n", {}, 'sub redefinition sets CvGV'; 53*foo = \&baz; 54*bar = *foo; 55eval 'sub bar { print +(caller 0)[3], "\n" }'; 56bar(); 57end 58 59fresh_perl_is 60 <<'end', "main::foo\nok\n", {}, 'no double free redefining anon stub'; 61my $sub = sub { 4 }; 62*foo = $sub; 63*bar = *foo; 64undef &$sub; 65eval 'sub bar { print +(caller 0)[3], "\n" }'; 66&$sub; 67undef *foo; 68undef *bar; 69print "ok\n"; 70end 71 72# The outer call sets the scalar returned by ${\""}.${\""} to the current 73# package name. 74# The inner call sets it to "road". 75# Each call records the value twice, the outer call surrounding the inner 76# call. In 5.10-5.18 under ithreads, what gets pushed is 77# qw(main road road road) because the inner call is clobbering the same 78# scalar. If __PACKAGE__ is changed to "main", it works, the last element 79# becoming "main". 80my @scratch; 81sub a { 82 for (${\""}.${\""}) { 83 $_ = $_[0]; 84 push @scratch, $_; 85 a("road",1) unless $_[1]; 86 push @scratch, $_; 87 } 88} 89a(__PACKAGE__); 90require Config; 91is "@scratch", "main road road main", 92 'recursive calls do not share shared-hash-key TARGs'; 93 94# Another test for the same bug, that does not rely on foreach. It depends 95# on ref returning a shared hash key TARG. 96undef @scratch; 97sub b { 98 my ($pack, $depth) = @_; 99 my $o = bless[], $pack; 100 $pack++; 101 push @scratch, (ref $o, $depth||b($pack,$depth+1))[0]; 102} 103b('n',0); 104is "@scratch", "o n", 105 'recursive calls do not share shared-hash-key TARGs (2)'; 106 107# [perl #78194] @_ aliasing op return values 108sub { is \$_[0], \$_[0], 109 '[perl #78194] \$_[0] == \$_[0] when @_ aliases "$x"' } 110 ->("${\''}"); 111 112# The return statement should make no difference in this case: 113sub not_constant () { 42 } 114sub not_constantr() { return 42 } 115use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; 116my sub not_constantm () { 42 } 117my sub not_constantmr() { return 42 } 118eval { ${\not_constant}++ }; 119is $@, "", 'sub (){42} returns a mutable value'; 120eval { ${\not_constantr}++ }; 121is $@, "", 'sub (){ return 42 } returns a mutable value'; 122eval { ${\not_constantm}++ }; 123is $@, "", 'my sub (){42} returns a mutable value'; 124eval { ${\not_constantmr}++ }; 125is $@, "", 'my sub (){ return 42 } returns a mutable value'; 126is eval { 127 sub Crunchy () { 1 } 128 sub Munchy { $_[0] = 2 } 129 eval "Crunchy"; # test that freeing this op does not turn off PADTMP 130 Munchy(Crunchy); 131} || $@, 2, 'freeing ops does not make sub(){42} immutable'; 132 133# &xsub when @_ has nonexistent elements 134{ 135 no warnings "uninitialized"; 136 local @_ = (); 137 $#_++; 138 &utf8::encode; 139 is @_, 1, 'num of elems in @_ after &xsub with nonexistent $_[0]'; 140 is $_[0], "", 'content of nonexistent $_[0] is modified by &xsub'; 141} 142 143# &xsub when @_ itself does not exist 144undef *_; 145eval { &utf8::encode }; 146# The main thing we are testing is that it did not crash. But make sure 147# *_{ARRAY} was untouched, too. 148is *_{ARRAY}, undef, 'goto &xsub when @_ does not exist'; 149 150# We do not want re.pm loaded at this point. Move this test up or find 151# another XSUB if this fails. 152ok !exists $INC{"re.pm"}, 're.pm not loaded yet'; 153{ 154 sub re::regmust{} 155 bless \&re::regmust; 156 DESTROY { 157 no warnings 'redefine', 'prototype'; 158 my $str1 = "$_[0]"; 159 *re::regmust = sub{}; # GvSV had no refcount, so this freed it 160 my $str2 = "$_[0]"; # used to be UNKNOWN(0x7fdda29310e0) 161 @str = ($str1, $str2); 162 } 163 local $^W; # Suppress redef warnings in XSLoader 164 require re; 165 is $str[1], $str[0], 166 'XSUB clobbering sub whose DESTROY assigns to the glob'; 167} 168{ 169 no warnings 'redefine'; 170 sub foo {} 171 bless \&foo, 'newATTRSUBbug'; 172 sub newATTRSUBbug::DESTROY { 173 my $str1 = "$_[0]"; 174 *foo = sub{}; # GvSV had no refcount, so this freed it 175 my $str2 = "$_[0]"; # used to be UNKNOWN(0x7fdda29310e0) 176 @str = ($str1, $str2); 177 } 178 splice @str; 179 eval "sub foo{}"; 180 is $str[1], $str[0], 181 'Pure-Perl sub clobbering sub whose DESTROY assigns to the glob'; 182} 183 184# [perl #122107] previously this would return 185# Subroutine BEGIN redefined at (eval 2) line 2. 186fresh_perl_is(<<'EOS', "", { stderr => 1 }, 187use strict; use warnings; eval q/use File::{Spec}/; eval q/use File::Spec/; 188EOS 189 "check special blocks are cleared on error"); 190 191use constant { constant1 => 1, constant2 => 2 }; 192{ 193 my $w; 194 local $SIG{__WARN__} = sub { $w++ }; 195 eval 'sub constant1; sub constant2($)'; 196 is eval '&constant1', '1', 197 'stub re-declaration of constant with no prototype'; 198 is eval '&constant2', '2', 199 'stub re-declaration of constant with wrong prototype'; 200 is $w, 2, 'two warnings from the above'; 201} 202 203package _122845 { 204 our $depth = 0; 205 my $parent; # just to make the sub a closure 206 207 sub { 208 local $depth = $depth + 1; 209 our $ok++, return if $depth == 2; 210 211 ()= $parent; # just to make the sub a closure 212 our $whatever; # this causes the crash 213 214 CORE::__SUB__->(); 215 }->(); 216}; 217is $_122845::ok, 1, 218 '[perl #122845] no crash in closure recursion with our-vars'; 219 220() = *predeclared; # vivify the glob at compile time 221sub predeclared; # now we have a CV stub with no body (incorporeal? :-) 222sub predeclared { 223 CORE::state $x = 42; 224 sub inside_predeclared { 225 is eval '$x', 42, 'eval q/$var/ in named sub in predeclared sub'; 226 } 227} 228predeclared(); # set $x to 42 229$main::x = $main::x = "You should not see this."; 230inside_predeclared(); # run test 231 232# RT #126845: this used to fail an assertion in Perl_newATTRSUB_x() 233eval 'sub rt126845_1 (); sub rt126845_1 () :lvalue'; 234pass("RT #126845: stub with prototype, then with attribute"); 235 236eval 'sub rt126845_2 (); sub rt126845_2 () :lvalue {}'; 237pass("RT #126845: stub with prototype, then definition with attribute"); 238 239# RT #124156 death during unwinding causes crash 240# the tie allows us to trigger another die while cleaning up the stack 241# from an earlier die. 242 243{ 244 package RT124156; 245 246 sub TIEHASH { bless({}, $_[0]) } 247 sub EXISTS { 0 } 248 sub FETCH { undef } 249 sub STORE { } 250 sub DELETE { die "outer\n" } 251 252 my @value; 253 eval { 254 @value = sub { 255 @value = sub { 256 my %a; 257 tie %a, "RT124156"; 258 local $a{foo} = "bar"; 259 die "inner"; 260 ("dd2a", "dd2b"); 261 }->(); 262 ("cc3a", "cc3b"); 263 }->(); 264 }; 265 ::is($@, "outer\n", "RT124156 plain"); 266 267 my $destroyed = 0; 268 sub DESTROY { $destroyed = 1 } 269 270 sub f { 271 my $x; 272 my $f = sub { 273 $x = 1; # force closure 274 my %a; 275 tie %a, "RT124156"; 276 local $a{foo} = "bar"; 277 die "inner"; 278 }; 279 bless $f, 'RT124156'; 280 $f->(); 281 } 282 283 eval { f(); }; 284 # as opposed to $@ eq "Can't undef active subroutine" 285 ::is($@, "outer\n", "RT124156 depth"); 286 ::is($destroyed, 1, "RT124156 freed cv"); 287} 288 289# trapping dying while popping a scope needs to have the right pad at all 290# times. Localising a tied array then dying in STORE raises an exception 291# while leaving g(). Note that using an object and destructor wouldn't be 292# sufficient since DESTROY is called with call_sv(...,G_EVAL). 293# We make sure that the first item in every sub's pad is a lexical with 294# different values per sub. 295 296{ 297 package tie_exception; 298 sub TIEARRAY { my $x = 4; bless [0] } 299 sub FETCH { my $x = 5; 1 } 300 sub STORE { my $x = 6; die if $_[0][0]; $_[0][0] = 1 } 301 302 my $y; 303 sub f { my $x = 7; eval { g() }; $y = $x } 304 sub g { 305 my $x = 8; 306 my @a; 307 tie @a, "tie_exception"; 308 local $a[0]; 309 } 310 311 f(); 312 ::is($y, 7, "tie_exception"); 313} 314 315 316# check that return pops extraneous stuff from the stack 317 318sub check_ret { 319 # the extra scopes push contexts and extra SVs on the stack 320 { 321 my @a = map $_ + 20, @_; 322 for ('x') { 323 return if defined $_[0] && $_[0] < 0; 324 } 325 for ('y') { 326 check_ret(1, do { (2,3,4, return @a ? @a[0..$#a] : ()) }, 4.5); 327 } 328 } 329} 330 331is(scalar check_ret(), undef, "check_ret() scalar"); 332is(scalar check_ret(5), 25, "check_ret(5) scalar"); 333is(scalar check_ret(5,6), 26, "check_ret(5,6) scalar"); 334is(scalar check_ret(5,6,7), 27, "check_ret(5,6,7) scalar"); 335is(scalar check_ret(5,6,7,8), 28, "check_ret(5,6,7,8) scalar"); 336is(scalar check_ret(5,6,7,8,9), 29, "check_ret(5,6,7,8,9) scalar"); 337 338is(scalar check_ret(-1), undef, "check_ret(-1) scalar"); 339is(scalar check_ret(-1,5), undef, "check_ret(-1,5) scalar"); 340 341is(join('-', 10, check_ret()), "10", "check_ret() list"); 342is(join('-', 10, check_ret(5)), "10-25", "check_ret(5) list"); 343is(join('-', 10, check_ret(5,6)), "10-25-26", "check_ret(5,6) list"); 344is(join('-', 10, check_ret(5,6,7)), "10-25-26-27", "check_ret(5,6,7) list"); 345is(join('-', 10, check_ret(5,6,7,8)), "10-25-26-27-28", "check_ret(5,6,7,8) list"); 346is(join('-', 10, check_ret(5,6,7,8,9)), "10-25-26-27-28-29", "check_ret(5,6,7,8,9) list"); 347 348is(join('-', 10, check_ret(-1)), "10", "check_ret(-1) list"); 349is(join('-', 10, check_ret(-1,5)), "10", "check_ret(-1,5) list"); 350 351# a sub without nested scopes that still leaves rubbish on the stack 352# which needs popping 353{ 354 my @res = sub { 355 my $false; 356 # conditional leaves rubbish on stack 357 return @_ unless $false and $false; 358 1; 359 }->('a','b'); 360 is(join('-', @res), "a-b", "unnested rubbish"); 361} 362 363# a sub should copy returned PADTMPs 364 365{ 366 sub f99 { $_[0] . "x" }; 367 my $a = [ f99(1), f99(2) ]; 368 is("@$a", "1x 2x", "PADTMPs copied on return"); 369} 370 371# A sub should FREETMPS on exit 372# RT #124248 373 374{ 375 package p124248; 376 my $d = 0; 377 sub DESTROY { $d++ } 378 sub f { ::is($d, 1, "RT 124248"); } 379 sub g { !!(my $x = bless []); } 380 f(g()); 381} 382 383# return should have the right PL_curpm while copying its return args 384 385sub curpm { 386 "b" =~ /(.)/; 387 { 388 "c" =~ /(.)/; 389 return $1; 390 } 391} 392"a" =~ /(.)/; 393is(curpm(), 'c', 'return and PL_curpm'); 394 395sub rt_129916 { 42 } 396is ref($main::{rt_129916}), 'CODE', 'simple sub stored as CV in stash (main::)'; 397{ 398 package RT129916; 399 sub foo { 42 } 400} 401{ 402 local $::TODO = "disabled for now"; 403 is ref($RT129916::{foo}), 'CODE', 'simple sub stored as CV in stash (non-main::)'; 404} 405 406# Calling xsub via ampersand syntax when @_ has holes 407SKIP: { 408 skip "no XS::APItest on miniperl" if is_miniperl; 409 require XS::APItest; 410 local *_; 411 $_[1] = 1; 412 &XS::APItest::unshift_and_set_defav; 413 is "@_", "42 43 1" 414} 415 416# [perl #129090] Crashes and hangs 417watchdog 10; 418{ no warnings; 419 eval '$a=qq|a$a|;my sub b;%c;sub c{sub b;sub c}'; 420} 421eval ' 422 ()= %d; 423 {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u);} 424 {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u);} 425 {my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u);} 426 CORE::state sub b; sub d { sub b {} sub d } 427 '; 428eval '()=%e; sub e { sub e; eval q|$x| } e;'; 429