| 1 | #!./perl |
| 2 | |
| 3 | BEGIN { |
| 4 | splice @INC, 0, 0, 't', '.'; |
| 5 | require Config; |
| 6 | if (($Config::Config{'extensions'} !~ /\bB\b/) ){ |
| 7 | print "1..0 # Skip -- Perl configured without B module\n"; |
| 8 | exit 0; |
| 9 | } |
| 10 | require 'test.pl'; |
| 11 | } |
| 12 | |
| 13 | use warnings; |
| 14 | use strict; |
| 15 | |
| 16 | my $tests = 52; # not counting those in the __DATA__ section |
| 17 | |
| 18 | use B::Deparse; |
| 19 | my $deparse = B::Deparse->new(); |
| 20 | isa_ok($deparse, 'B::Deparse', 'instantiate a B::Deparse object'); |
| 21 | my %deparse; |
| 22 | |
| 23 | sub dummy_sub {42} |
| 24 | |
| 25 | $/ = "\n####\n"; |
| 26 | while (<DATA>) { |
| 27 | chomp; |
| 28 | $tests ++; |
| 29 | # This code is pinched from the t/lib/common.pl for TODO. |
| 30 | # It's not clear how to avoid duplication |
| 31 | my %meta = (context => ''); |
| 32 | foreach my $what (qw(skip todo context options)) { |
| 33 | s/^#\s*\U$what\E\s*(.*)\n//m and $meta{$what} = $1; |
| 34 | # If the SKIP reason starts ? then it's taken as a code snippet to |
| 35 | # evaluate. This provides the flexibility to have conditional SKIPs |
| 36 | if ($meta{$what} && $meta{$what} =~ s/^\?//) { |
| 37 | my $temp = eval $meta{$what}; |
| 38 | if ($@) { |
| 39 | die "# In \U$what\E code reason:\n# $meta{$what}\n$@"; |
| 40 | } |
| 41 | $meta{$what} = $temp; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | s/^\s*#\s*(.*)$//mg; |
| 46 | my $desc = $1; |
| 47 | die "Missing name in test $_" unless defined $desc; |
| 48 | |
| 49 | if ($meta{skip}) { |
| 50 | SKIP: { skip($meta{skip}) }; |
| 51 | next; |
| 52 | } |
| 53 | |
| 54 | my ($input, $expected); |
| 55 | if (/(.*)\n>>>>\n(.*)/s) { |
| 56 | ($input, $expected) = ($1, $2); |
| 57 | } |
| 58 | else { |
| 59 | ($input, $expected) = ($_, $_); |
| 60 | } |
| 61 | |
| 62 | # parse options if necessary |
| 63 | my $deparse = $meta{options} |
| 64 | ? $deparse{$meta{options}} ||= |
| 65 | B::Deparse->new(split /,/, $meta{options}) |
| 66 | : $deparse; |
| 67 | |
| 68 | my $code = "$meta{context};\n" . <<'EOC' . "sub {$input\n}"; |
| 69 | # Tell B::Deparse about our ambient pragmas |
| 70 | my ($hint_bits, $warning_bits, $hinthash); |
| 71 | BEGIN { |
| 72 | ($hint_bits, $warning_bits, $hinthash) = ($^H, ${^WARNING_BITS}, \%^H); |
| 73 | } |
| 74 | $deparse->ambient_pragmas ( |
| 75 | hint_bits => $hint_bits, |
| 76 | warning_bits => $warning_bits, |
| 77 | '%^H' => $hinthash, |
| 78 | ); |
| 79 | EOC |
| 80 | my $coderef = eval $code; |
| 81 | |
| 82 | local $::TODO = $meta{todo}; |
| 83 | if ($@) { |
| 84 | is($@, "", "compilation of $desc") |
| 85 | or diag "=============================================\n" |
| 86 | . "CODE:\n--------\n$code\n--------\n" |
| 87 | . "=============================================\n"; |
| 88 | } |
| 89 | else { |
| 90 | my $deparsed = $deparse->coderef2text( $coderef ); |
| 91 | my $regex = $expected; |
| 92 | $regex =~ s/(\S+)/\Q$1/g; |
| 93 | $regex =~ s/\s+/\\s+/g; |
| 94 | $regex = '^\{\s*' . $regex . '\s*\}$'; |
| 95 | |
| 96 | like($deparsed, qr/$regex/, $desc) |
| 97 | or diag "=============================================\n" |
| 98 | . "CODE:\n--------\n$input\n--------\n" |
| 99 | . "EXPECTED:\n--------\n{\n$expected\n}\n--------\n" |
| 100 | . "GOT:\n--------\n$deparsed\n--------\n" |
| 101 | . "=============================================\n"; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | # Reset the ambient pragmas |
| 106 | { |
| 107 | my ($b, $w, $h); |
| 108 | BEGIN { |
| 109 | ($b, $w, $h) = ($^H, ${^WARNING_BITS}, \%^H); |
| 110 | } |
| 111 | $deparse->ambient_pragmas ( |
| 112 | hint_bits => $b, |
| 113 | warning_bits => $w, |
| 114 | '%^H' => $h, |
| 115 | ); |
| 116 | } |
| 117 | |
| 118 | use constant 'c', 'stuff'; |
| 119 | is((eval "sub ".$deparse->coderef2text(\&c))->(), 'stuff', |
| 120 | 'the subroutine generated by use constant deparses'); |
| 121 | |
| 122 | my $a = 0; |
| 123 | is($deparse->coderef2text(sub{(-1) ** $a }), "{\n (-1) ** \$a;\n}", |
| 124 | 'anon sub capturing an external lexical'); |
| 125 | |
| 126 | use constant cr => ['hello']; |
| 127 | my $string = "sub " . $deparse->coderef2text(\&cr); |
| 128 | my $val = (eval $string)->() or diag $string; |
| 129 | is(ref($val), 'ARRAY', 'constant array references deparse'); |
| 130 | is($val->[0], 'hello', 'and return the correct value'); |
| 131 | |
| 132 | my $path = join " ", map { qq["-I$_"] } @INC; |
| 133 | |
| 134 | $a = `$^X $path "-MO=Deparse" -anlwi.bak -e 1 2>&1`; |
| 135 | $a =~ s/-e syntax OK\n//g; |
| 136 | $a =~ s/.*possible typo.*\n//; # Remove warning line |
| 137 | $a =~ s/.*-i used with no filenames.*\n//; # Remove warning line |
| 138 | $b = quotemeta <<'EOF'; |
| 139 | BEGIN { $^I = ".bak"; } |
| 140 | BEGIN { $^W = 1; } |
| 141 | BEGIN { $/ = "\n"; $\ = "\n"; } |
| 142 | LINE: while (defined($_ = readline ARGV)) { |
| 143 | chomp $_; |
| 144 | our(@F) = split(' ', $_, 0); |
| 145 | '???'; |
| 146 | } |
| 147 | EOF |
| 148 | $b =~ s/our\\\(\\\@F\\\)/our[( ]\@F\\)?/; # accept both our @F and our(@F) |
| 149 | like($a, qr/$b/, |
| 150 | 'command line flags deparse as BEGIN blocks setting control variables'); |
| 151 | |
| 152 | $a = `$^X $path "-MO=Deparse" -e "use constant PI => 4" 2>&1`; |
| 153 | $a =~ s/-e syntax OK\n//g; |
| 154 | is($a, "use constant ('PI', 4);\n", |
| 155 | "Proxy Constant Subroutines must not show up as (incorrect) prototypes"); |
| 156 | |
| 157 | $a = `$^X $path "-MO=Deparse" -e "sub foo(){1}" 2>&1`; |
| 158 | $a =~ s/-e syntax OK\n//g; |
| 159 | is($a, "sub foo () {\n 1;\n}\n", |
| 160 | "Main prog consisting of just a constant (via empty proto)"); |
| 161 | |
| 162 | $a = readpipe qq|$^X $path "-MO=Deparse"| |
| 163 | .qq| -e "package F; sub f(){0} sub s{}"| |
| 164 | .qq| -e "#line 123 four-five-six"| |
| 165 | .qq| -e "package G; sub g(){0} sub s{}" 2>&1|; |
| 166 | $a =~ s/-e syntax OK\n//g; |
| 167 | like($a, qr/sub F::f \(\) \{\s*0;?\s*}/, |
| 168 | "Constant is dumped in package in which other subs are dumped"); |
| 169 | unlike($a, qr/sub g/, |
| 170 | "Constant is not dumped in package in which other subs are not dumped"); |
| 171 | |
| 172 | #Re: perlbug #35857, patch #24505 |
| 173 | #handle warnings::register-ed packages properly. |
| 174 | package B::Deparse::Wrapper; |
| 175 | use strict; |
| 176 | use warnings; |
| 177 | use warnings::register; |
| 178 | sub getcode { |
| 179 | my $deparser = B::Deparse->new(); |
| 180 | return $deparser->coderef2text(shift); |
| 181 | } |
| 182 | |
| 183 | package Moo; |
| 184 | use overload '0+' => sub { 42 }; |
| 185 | |
| 186 | package main; |
| 187 | use strict; |
| 188 | use warnings; |
| 189 | use constant GLIPP => 'glipp'; |
| 190 | use constant PI => 4; |
| 191 | use constant OVERLOADED_NUMIFICATION => bless({}, 'Moo'); |
| 192 | use Fcntl qw/O_TRUNC O_APPEND O_EXCL/; |
| 193 | BEGIN { delete $::Fcntl::{O_APPEND}; } |
| 194 | use POSIX qw/O_CREAT/; |
| 195 | sub test { |
| 196 | my $val = shift; |
| 197 | my $res = B::Deparse::Wrapper::getcode($val); |
| 198 | like($res, qr/use warnings/, |
| 199 | '[perl #35857] [PATCH] B::Deparse doesnt handle warnings register properly'); |
| 200 | } |
| 201 | my ($q,$p); |
| 202 | my $x=sub { ++$q,++$p }; |
| 203 | test($x); |
| 204 | eval <<EOFCODE and test($x); |
| 205 | package bar; |
| 206 | use strict; |
| 207 | use warnings; |
| 208 | use warnings::register; |
| 209 | package main; |
| 210 | 1 |
| 211 | EOFCODE |
| 212 | |
| 213 | # Exotic sub declarations |
| 214 | $a = `$^X $path "-MO=Deparse" -e "sub ::::{}sub ::::::{}" 2>&1`; |
| 215 | $a =~ s/-e syntax OK\n//g; |
| 216 | is($a, <<'EOCODG', "sub :::: and sub ::::::"); |
| 217 | sub :::: { |
| 218 | |
| 219 | } |
| 220 | sub :::::: { |
| 221 | |
| 222 | } |
| 223 | EOCODG |
| 224 | |
| 225 | # [perl #117311] |
| 226 | $a = `$^X $path "-MO=Deparse,-l" -e "map{ eval(0) }()" 2>&1`; |
| 227 | $a =~ s/-e syntax OK\n//g; |
| 228 | is($a, <<'EOCODH', "[perl #117311] [PATCH] -l option ('#line ...') does not emit ^Ls in the output"); |
| 229 | #line 1 "-e" |
| 230 | map { |
| 231 | #line 1 "-e" |
| 232 | eval 0;} (); |
| 233 | EOCODH |
| 234 | |
| 235 | # [perl #33752] |
| 236 | { |
| 237 | my $code = <<"EOCODE"; |
| 238 | { |
| 239 | our \$\x{1e1f}\x{14d}\x{14d}; |
| 240 | } |
| 241 | EOCODE |
| 242 | my $deparsed |
| 243 | = $deparse->coderef2text(eval "sub { our \$\x{1e1f}\x{14d}\x{14d} }" ); |
| 244 | s/$ \n//x for $deparsed, $code; |
| 245 | is $deparsed, $code, 'our $funny_Unicode_chars'; |
| 246 | } |
| 247 | |
| 248 | # [perl #62500] |
| 249 | $a = |
| 250 | `$^X $path "-MO=Deparse" -e "BEGIN{*CORE::GLOBAL::require=sub{1}}" 2>&1`; |
| 251 | $a =~ s/-e syntax OK\n//g; |
| 252 | is($a, <<'EOCODF', "CORE::GLOBAL::require override causing panick"); |
| 253 | sub BEGIN { |
| 254 | *CORE::GLOBAL::require = sub { |
| 255 | 1; |
| 256 | } |
| 257 | ; |
| 258 | } |
| 259 | EOCODF |
| 260 | |
| 261 | # [perl #91384] |
| 262 | $a = |
| 263 | `$^X $path "-MO=Deparse" -e "BEGIN{*Acme::Acme:: = *Acme::}" 2>&1`; |
| 264 | like($a, qr/-e syntax OK/, |
| 265 | "Deparse does not hang when traversing stash circularities"); |
| 266 | |
| 267 | # [perl #93990] |
| 268 | @] = (); |
| 269 | is($deparse->coderef2text(sub{ print "foo@{]}" }), |
| 270 | q<{ |
| 271 | print "foo@{]}"; |
| 272 | }>, 'curly around to interpolate "@{]}"'); |
| 273 | is($deparse->coderef2text(sub{ print "foo@{-}" }), |
| 274 | q<{ |
| 275 | print "foo@-"; |
| 276 | }>, 'no need to curly around to interpolate "@-"'); |
| 277 | |
| 278 | # Strict hints in %^H are mercilessly suppressed |
| 279 | $a = |
| 280 | `$^X $path "-MO=Deparse" -e "use strict; print;" 2>&1`; |
| 281 | unlike($a, qr/BEGIN/, |
| 282 | "Deparse does not emit strict hh hints"); |
| 283 | |
| 284 | # ambient_pragmas should not mess with strict settings. |
| 285 | SKIP: { |
| 286 | skip "requires 5.11", 1 unless $] >= 5.011; |
| 287 | eval q` |
| 288 | BEGIN { |
| 289 | # Clear out all hints |
| 290 | %^H = (); |
| 291 | $^H = 0; |
| 292 | B::Deparse->new->ambient_pragmas(strict => 'all'); |
| 293 | } |
| 294 | use 5.011; # should enable strict |
| 295 | ok !eval '$do_noT_create_a_variable_with_this_name = 1', |
| 296 | 'ambient_pragmas do not mess with compiling scope'; |
| 297 | `; |
| 298 | } |
| 299 | |
| 300 | # multiple statements on format lines |
| 301 | $a = `$^X $path "-MO=Deparse" -e "format =" -e "\@" -e "x();z()" -e. 2>&1`; |
| 302 | $a =~ s/-e syntax OK\n//g; |
| 303 | is($a, <<'EOCODH', 'multiple statements on format lines'); |
| 304 | format STDOUT = |
| 305 | @ |
| 306 | x(); z() |
| 307 | . |
| 308 | EOCODH |
| 309 | |
| 310 | SKIP: { |
| 311 | skip("Your perl was built without taint support", 1) |
| 312 | unless $Config::Config{taint_support}; |
| 313 | |
| 314 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path, '-T' ], |
| 315 | prog => "format =\n\@\n\$;\n.\n"), |
| 316 | <<~'EOCODM', '$; on format line'; |
| 317 | format STDOUT = |
| 318 | @ |
| 319 | $; |
| 320 | . |
| 321 | EOCODM |
| 322 | } |
| 323 | |
| 324 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse,-l', $path ], |
| 325 | prog => "format =\n\@\n\$foo\n.\n"), |
| 326 | <<'EOCODM', 'formats with -l'; |
| 327 | format STDOUT = |
| 328 | @ |
| 329 | $foo |
| 330 | . |
| 331 | EOCODM |
| 332 | |
| 333 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 334 | prog => "{ my \$x; format =\n\@\n\$x\n.\n}"), |
| 335 | <<'EOCODN', 'formats nested inside blocks'; |
| 336 | { |
| 337 | my $x; |
| 338 | format STDOUT = |
| 339 | @ |
| 340 | $x |
| 341 | . |
| 342 | } |
| 343 | EOCODN |
| 344 | |
| 345 | # CORE::format |
| 346 | $a = readpipe qq`$^X $path "-MO=Deparse" -e "use feature q|:all|;` |
| 347 | .qq` my sub format; CORE::format =" -e. 2>&1`; |
| 348 | like($a, qr/CORE::format/, 'CORE::format when lex format sub is in scope'); |
| 349 | |
| 350 | # literal big chars under 'use utf8' |
| 351 | is($deparse->coderef2text(sub{ use utf8; /€/; }), |
| 352 | '{ |
| 353 | /\x{20ac}/; |
| 354 | }', |
| 355 | "qr/euro/"); |
| 356 | |
| 357 | # STDERR when deparsing sub calls |
| 358 | # For a short while the output included 'While deparsing' |
| 359 | $a = `$^X $path "-MO=Deparse" -e "foo()" 2>&1`; |
| 360 | $a =~ s/-e syntax OK\n//g; |
| 361 | is($a, <<'EOCODI', 'no extra output when deparsing foo()'); |
| 362 | foo(); |
| 363 | EOCODI |
| 364 | |
| 365 | # Sub calls compiled before importation |
| 366 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 367 | prog => 'BEGIN { |
| 368 | require Test::More; |
| 369 | Test::More::->import; |
| 370 | is(*foo, *foo) |
| 371 | }'), |
| 372 | qr/&is\(/, |
| 373 | 'sub calls compiled before importation of prototype subs'; |
| 374 | |
| 375 | # [perl #121050] Prototypes with whitespace |
| 376 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 377 | prog => <<'EOCODO'), |
| 378 | sub _121050(\$ \$) { } |
| 379 | _121050($a,$b); |
| 380 | sub _121050empty( ) {} |
| 381 | () = _121050empty() + 1; |
| 382 | EOCODO |
| 383 | <<'EOCODP', '[perl #121050] prototypes with whitespace'; |
| 384 | sub _121050 (\$ \$) { |
| 385 | |
| 386 | } |
| 387 | _121050 $a, $b; |
| 388 | sub _121050empty ( ) { |
| 389 | |
| 390 | } |
| 391 | () = _121050empty + 1; |
| 392 | EOCODP |
| 393 | |
| 394 | # CORE::no |
| 395 | $a = readpipe qq`$^X $path "-MO=Deparse" -Xe ` |
| 396 | .qq`"use feature q|:all|; my sub no; CORE::no less" 2>&1`; |
| 397 | like($a, qr/my sub no;\n.*CORE::no less;/s, |
| 398 | 'CORE::no after my sub no'); |
| 399 | |
| 400 | # CORE::use |
| 401 | $a = readpipe qq`$^X $path "-MO=Deparse" -Xe ` |
| 402 | .qq`"use feature q|:all|; my sub use; CORE::use less" 2>&1`; |
| 403 | like($a, qr/my sub use;\n.*CORE::use less;/s, |
| 404 | 'CORE::use after my sub use'); |
| 405 | |
| 406 | # CORE::__DATA__ |
| 407 | $a = readpipe qq`$^X $path "-MO=Deparse" -Xe ` |
| 408 | .qq`"use feature q|:all|; my sub __DATA__; ` |
| 409 | .qq`CORE::__DATA__" 2>&1`; |
| 410 | like($a, qr/my sub __DATA__;\n.*CORE::__DATA__/s, |
| 411 | 'CORE::__DATA__ after my sub __DATA__'); |
| 412 | |
| 413 | # sub declarations |
| 414 | $a = readpipe qq`$^X $path "-MO=Deparse" -e "sub foo{}" 2>&1`; |
| 415 | like($a, qr/sub foo\s*\{\s+\}/, 'sub declarations'); |
| 416 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 417 | prog => 'sub f($); sub f($){}'), |
| 418 | qr/sub f\s*\(\$\)\s*\{\s*\}/, |
| 419 | 'predeclared prototyped subs'; |
| 420 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 421 | prog => 'sub f($); |
| 422 | BEGIN { use builtin q-weaken-; weaken($_=\$::{f}) }'), |
| 423 | qr/sub f\s*\(\$\)\s*;/, |
| 424 | 'prototyped stub with weak reference to the stash entry'; |
| 425 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 426 | prog => 'sub f () { 42 }'), |
| 427 | qr/sub f\s*\(\)\s*\{\s*42;\s*\}/, |
| 428 | 'constant perl sub declaration'; |
| 429 | |
| 430 | # BEGIN blocks |
| 431 | SKIP : { |
| 432 | skip "BEGIN output is wrong on old perls", 1 if $] < 5.021006; |
| 433 | my $prog = ' |
| 434 | BEGIN { pop } |
| 435 | { |
| 436 | BEGIN { pop } |
| 437 | { |
| 438 | no overloading; |
| 439 | { |
| 440 | BEGIN { pop } |
| 441 | die |
| 442 | } |
| 443 | } |
| 444 | }'; |
| 445 | $prog =~ s/\n//g; |
| 446 | $a = readpipe qq`$^X $path "-MO=Deparse" -e "$prog" 2>&1`; |
| 447 | $a =~ s/-e syntax OK\n//g; |
| 448 | is($a, <<'EOCODJ', 'BEGIN blocks'); |
| 449 | sub BEGIN { |
| 450 | pop @ARGV; |
| 451 | } |
| 452 | { |
| 453 | sub BEGIN { |
| 454 | pop @ARGV; |
| 455 | } |
| 456 | { |
| 457 | no overloading; |
| 458 | { |
| 459 | sub BEGIN { |
| 460 | pop @ARGV; |
| 461 | } |
| 462 | die; |
| 463 | } |
| 464 | } |
| 465 | } |
| 466 | EOCODJ |
| 467 | } |
| 468 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], prog => ' |
| 469 | { |
| 470 | { |
| 471 | die; |
| 472 | BEGIN { pop } |
| 473 | } |
| 474 | BEGIN { pop } |
| 475 | } |
| 476 | BEGIN { pop } |
| 477 | '), <<'EOCODL', 'BEGIN blocks at the end of their enclosing blocks'; |
| 478 | { |
| 479 | { |
| 480 | die; |
| 481 | sub BEGIN { |
| 482 | pop @ARGV; |
| 483 | } |
| 484 | } |
| 485 | sub BEGIN { |
| 486 | pop @ARGV; |
| 487 | } |
| 488 | } |
| 489 | sub BEGIN { |
| 490 | pop @ARGV; |
| 491 | } |
| 492 | EOCODL |
| 493 | |
| 494 | # BEGIN blocks should not be called __ANON__ |
| 495 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 496 | prog => 'sub BEGIN { } CHECK { delete $::{BEGIN} }'), |
| 497 | qr/sub BEGIN/, 'anonymised BEGIN'; |
| 498 | |
| 499 | # [perl #115066] |
| 500 | my $prog = 'use constant FOO => do { 1 }; no overloading; die'; |
| 501 | $a = readpipe qq`$^X $path "-MO=-qq,Deparse" -e "$prog" 2>&1`; |
| 502 | is($a, <<'EOCODK', '[perl #115066] use statements accidentally nested'); |
| 503 | use constant ('FOO', do { |
| 504 | 1 |
| 505 | }); |
| 506 | no overloading; |
| 507 | die; |
| 508 | EOCODK |
| 509 | |
| 510 | # BEGIN blocks inside predeclared subs |
| 511 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 512 | prog => ' |
| 513 | sub run_tests; |
| 514 | run_tests(); |
| 515 | sub run_tests { BEGIN { } die }'), |
| 516 | qr/sub run_tests \{\s*sub BEGIN/, |
| 517 | 'BEGIN block inside predeclared sub'; |
| 518 | |
| 519 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 520 | prog => 'package foo; use overload qr=>sub{}'), |
| 521 | qr/package foo;\s*use overload/, |
| 522 | 'package, then use'; |
| 523 | |
| 524 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 525 | prog => 'use feature lexical_subs=>; my sub f;sub main::f{}'), |
| 526 | qr/^sub main::f \{/m, |
| 527 | 'sub decl when lex sub is in scope'; |
| 528 | |
| 529 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 530 | prog => 'sub foo{foo()}'), |
| 531 | qr/^sub foo \{\s+foo\(\)/m, |
| 532 | 'recursive sub'; |
| 533 | |
| 534 | like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 535 | prog => 'use feature lexical_subs=>state=>; |
| 536 | state sub sb5; sub { sub sb5 { } }'), |
| 537 | qr/sub \{\s*\(\);\s*sub sb5 \{/m, |
| 538 | 'state sub in anon sub but declared outside'; |
| 539 | |
| 540 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 541 | prog => 'BEGIN { $::{f}=\!0 }'), |
| 542 | "sub BEGIN {\n \$main::{'f'} = \\!0;\n}\n", |
| 543 | '&PL_sv_yes constant (used to croak)'; |
| 544 | |
| 545 | SKIP: { |
| 546 | skip("Your perl was built without taint support", 1) |
| 547 | unless $Config::Config{taint_support}; |
| 548 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path, '-T' ], |
| 549 | prog => '$x =~ (1?/$a/:0)'), |
| 550 | '$x =~ ($_ =~ /$a/);'."\n", |
| 551 | '$foo =~ <branch-folded match> under taint mode'; |
| 552 | } |
| 553 | |
| 554 | unlike runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path, '-w' ], |
| 555 | prog => 'BEGIN { undef &foo }'), |
| 556 | qr'Use of uninitialized value', |
| 557 | 'no warnings for undefined sub'; |
| 558 | |
| 559 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 560 | prog => 'sub f { 1; } BEGIN { *g = \&f; }'), |
| 561 | "sub f {\n 1;\n}\nsub BEGIN {\n *g = \\&f;\n}\n", |
| 562 | "sub glob alias shouldn't impede emitting original sub"; |
| 563 | |
| 564 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 565 | prog => 'package Foo; sub f { 1; } BEGIN { *g = \&f; }'), |
| 566 | "package Foo;\nsub f {\n 1;\n}\nsub BEGIN {\n *g = \\&f;\n}\n", |
| 567 | "sub glob alias outside main shouldn't impede emitting original sub"; |
| 568 | |
| 569 | is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], |
| 570 | prog => 'package Foo; sub f { 1; } BEGIN { *Bar::f = \&f; }'), |
| 571 | "package Foo;\nsub f {\n 1;\n}\nsub BEGIN {\n *Bar::f = \\&f;\n}\n", |
| 572 | "sub glob alias in separate package shouldn't impede emitting original sub"; |
| 573 | |
| 574 | |
| 575 | done_testing($tests); |
| 576 | |
| 577 | __DATA__ |
| 578 | # [perl #120950] Previously on a 2nd instance succeeded |
| 579 | # y/uni/code/ |
| 580 | tr/\x{345}/\x{370}/; |
| 581 | #### |
| 582 | # y/uni/code/ [perl #120950] This 2nd instance succeeds |
| 583 | tr/\x{345}/\x{370}/; |
| 584 | #### |
| 585 | # A constant |
| 586 | 1; |
| 587 | #### |
| 588 | # Constants in a block |
| 589 | # CONTEXT no warnings; |
| 590 | { |
| 591 | '???'; |
| 592 | 2; |
| 593 | } |
| 594 | #### |
| 595 | # List of constants in void context |
| 596 | # CONTEXT no warnings; |
| 597 | (1,2,3); |
| 598 | 0; |
| 599 | >>>> |
| 600 | '???', '???', '???'; |
| 601 | 0; |
| 602 | #### |
| 603 | # Lexical and simple arithmetic |
| 604 | my $test; |
| 605 | ++$test and $test /= 2; |
| 606 | >>>> |
| 607 | my $test; |
| 608 | $test /= 2 if ++$test; |
| 609 | #### |
| 610 | # list x |
| 611 | -((1, 2) x 2); |
| 612 | #### |
| 613 | # Assignment to list x |
| 614 | ((undef) x 3) = undef; |
| 615 | #### |
| 616 | # lvalue sub |
| 617 | { |
| 618 | my $test = sub : lvalue { |
| 619 | my $x; |
| 620 | } |
| 621 | ; |
| 622 | } |
| 623 | #### |
| 624 | # method |
| 625 | { |
| 626 | my $test = sub : method { |
| 627 | my $x; |
| 628 | } |
| 629 | ; |
| 630 | } |
| 631 | #### |
| 632 | # anonsub attrs at statement start |
| 633 | my $x = do { +sub : lvalue { my $y; } }; |
| 634 | my $z = do { foo: +sub : method { my $a; } }; |
| 635 | #### |
| 636 | # block with continue |
| 637 | { |
| 638 | 234; |
| 639 | } |
| 640 | continue { |
| 641 | 123; |
| 642 | } |
| 643 | #### |
| 644 | # lexical and package scalars |
| 645 | my $x; |
| 646 | print $main::x; |
| 647 | #### |
| 648 | # lexical and package arrays |
| 649 | my @x; |
| 650 | print $main::x[1]; |
| 651 | print \my @a; |
| 652 | #### |
| 653 | # lexical and package hashes |
| 654 | my %x; |
| 655 | $x{warn()}; |
| 656 | #### |
| 657 | # our (LIST) |
| 658 | our($foo, $bar, $baz); |
| 659 | #### |
| 660 | # CONTEXT { package Dog } use feature "state"; |
| 661 | # variables with declared classes |
| 662 | my Dog $spot; |
| 663 | our Dog $spotty; |
| 664 | state Dog $spotted; |
| 665 | my Dog @spot; |
| 666 | our Dog @spotty; |
| 667 | state Dog @spotted; |
| 668 | my Dog %spot; |
| 669 | our Dog %spotty; |
| 670 | state Dog %spotted; |
| 671 | my Dog ($foo, @bar, %baz); |
| 672 | our Dog ($phoo, @barr, %bazz); |
| 673 | state Dog ($fough, @barre, %bazze); |
| 674 | #### |
| 675 | # local our |
| 676 | local our $rhubarb; |
| 677 | local our($rhu, $barb); |
| 678 | #### |
| 679 | # <> |
| 680 | my $foo; |
| 681 | $_ .= <> . <ARGV> . <$foo>; |
| 682 | <$foo>; |
| 683 | <${foo}>; |
| 684 | <$ foo>; |
| 685 | >>>> |
| 686 | my $foo; |
| 687 | $_ .= readline(ARGV) . readline(ARGV) . readline($foo); |
| 688 | readline $foo; |
| 689 | glob $foo; |
| 690 | glob $foo; |
| 691 | #### |
| 692 | # more <> |
| 693 | no warnings; |
| 694 | no strict; |
| 695 | my $fh; |
| 696 | if (dummy_sub < $fh > /bar/g) { 1 } |
| 697 | >>>> |
| 698 | no warnings; |
| 699 | no strict; |
| 700 | my $fh; |
| 701 | if (dummy_sub(glob((' ' . $fh . ' ')) / 'bar' / 'g')) { |
| 702 | 1; |
| 703 | } |
| 704 | #### |
| 705 | # readline |
| 706 | readline 'FH'; |
| 707 | readline *$_; |
| 708 | readline *{$_}; |
| 709 | readline ${"a"}; |
| 710 | >>>> |
| 711 | readline 'FH'; |
| 712 | readline *$_; |
| 713 | readline *{$_;}; |
| 714 | readline ${'a';}; |
| 715 | #### |
| 716 | # <<>> |
| 717 | $_ = <<>>; |
| 718 | #### |
| 719 | # \x{} |
| 720 | my $foo = "Ab\x{100}\200\x{200}\237Cd\000Ef\x{1000}\cA\x{2000}\cZ"; |
| 721 | my $bar = "\x{100}"; |
| 722 | #### |
| 723 | # Latin-1 chars |
| 724 | # TODO ? ord("A") != 65 && "EBCDIC" |
| 725 | my $baz = "B\366\x{100}"; |
| 726 | my $bba = qr/B\366\x{100}/; |
| 727 | #### |
| 728 | # s///e |
| 729 | s/x/'y';/e; |
| 730 | s/x/$a;/e; |
| 731 | s/x/complex_expression();/e; |
| 732 | #### |
| 733 | # block |
| 734 | { my $x; } |
| 735 | #### |
| 736 | # while 1 |
| 737 | while (1) { my $k; } |
| 738 | #### |
| 739 | # trailing for |
| 740 | my ($x,@a); |
| 741 | $x=1 for @a; |
| 742 | >>>> |
| 743 | my($x, @a); |
| 744 | $x = 1 foreach (@a); |
| 745 | #### |
| 746 | # 2 arguments in a 3 argument for |
| 747 | for (my $i = 0; $i < 2;) { |
| 748 | my $z = 1; |
| 749 | } |
| 750 | #### |
| 751 | # 3 argument for |
| 752 | for (my $i = 0; $i < 2; ++$i) { |
| 753 | my $z = 1; |
| 754 | } |
| 755 | #### |
| 756 | # 3 argument for again |
| 757 | for (my $i = 0; $i < 2; ++$i) { |
| 758 | my $z = 1; |
| 759 | } |
| 760 | #### |
| 761 | # 3-argument for with inverted condition |
| 762 | for (my $i; not $i;) { |
| 763 | die; |
| 764 | } |
| 765 | for (my $i; not $i; ++$i) { |
| 766 | die; |
| 767 | } |
| 768 | for (my $a; not +($1 || 2) ** 2;) { |
| 769 | die; |
| 770 | } |
| 771 | Something_to_put_the_loop_in_void_context(); |
| 772 | #### |
| 773 | # while/continue |
| 774 | my $i; |
| 775 | while ($i) { my $z = 1; } continue { $i = 99; } |
| 776 | #### |
| 777 | # foreach with my |
| 778 | foreach my $i (1, 2) { |
| 779 | my $z = 1; |
| 780 | } |
| 781 | #### |
| 782 | # OPTIONS -p |
| 783 | # foreach with my under -p |
| 784 | foreach my $i (1) { |
| 785 | die; |
| 786 | } |
| 787 | #### |
| 788 | # foreach |
| 789 | my $i; |
| 790 | foreach $i (1, 2) { |
| 791 | my $z = 1; |
| 792 | } |
| 793 | #### |
| 794 | # foreach, 2 mys |
| 795 | my $i; |
| 796 | foreach my $i (1, 2) { |
| 797 | my $z = 1; |
| 798 | } |
| 799 | #### |
| 800 | # foreach with our |
| 801 | foreach our $i (1, 2) { |
| 802 | my $z = 1; |
| 803 | } |
| 804 | #### |
| 805 | # foreach with my and our |
| 806 | my $i; |
| 807 | foreach our $i (1, 2) { |
| 808 | my $z = 1; |
| 809 | } |
| 810 | #### |
| 811 | # foreach with state |
| 812 | # CONTEXT use feature "state"; |
| 813 | foreach state $i (1, 2) { |
| 814 | state $z = 1; |
| 815 | } |
| 816 | #### |
| 817 | # foreach with sub call |
| 818 | foreach $_ (hcaerof()) { |
| 819 | (); |
| 820 | } |
| 821 | #### |
| 822 | # reverse sort |
| 823 | my @x; |
| 824 | print reverse sort(@x); |
| 825 | #### |
| 826 | # sort with cmp |
| 827 | my @x; |
| 828 | print((sort {$b cmp $a} @x)); |
| 829 | #### |
| 830 | # reverse sort with block |
| 831 | my @x; |
| 832 | print((reverse sort {$b <=> $a} @x)); |
| 833 | #### |
| 834 | # foreach reverse |
| 835 | our @a; |
| 836 | print $_ foreach (reverse @a); |
| 837 | #### |
| 838 | # foreach reverse (not inplace) |
| 839 | our @a; |
| 840 | print $_ foreach (reverse 1, 2..5); |
| 841 | #### |
| 842 | # bug #38684 |
| 843 | our @ary; |
| 844 | @ary = split(' ', 'foo', 0); |
| 845 | #### |
| 846 | my @ary; |
| 847 | @ary = split(' ', 'foo', 0); |
| 848 | #### |
| 849 | # Split to our array |
| 850 | our @array = split(//, 'foo', 0); |
| 851 | #### |
| 852 | # Split to my array |
| 853 | my @array = split(//, 'foo', 0); |
| 854 | #### |
| 855 | our @array; |
| 856 | my $c; |
| 857 | @array = split(/x(?{ $c++; })y/, 'foo', 0); |
| 858 | #### |
| 859 | my($x, $y, $p); |
| 860 | our $c; |
| 861 | ($x, $y) = split(/$p(?{ $c++; })y/, 'foo', 2); |
| 862 | #### |
| 863 | our @ary; |
| 864 | my $pat; |
| 865 | @ary = split(/$pat/, 'foo', 0); |
| 866 | #### |
| 867 | my @ary; |
| 868 | our $pat; |
| 869 | @ary = split(/$pat/, 'foo', 0); |
| 870 | #### |
| 871 | our @array; |
| 872 | my $pat; |
| 873 | local @array = split(/$pat/, 'foo', 0); |
| 874 | #### |
| 875 | our $pat; |
| 876 | my @array = split(/$pat/, 'foo', 0); |
| 877 | #### |
| 878 | # bug #40055 |
| 879 | do { () }; |
| 880 | #### |
| 881 | # bug #40055 |
| 882 | do { my $x = 1; $x }; |
| 883 | #### |
| 884 | # <20061012113037.GJ25805@c4.convolution.nl> |
| 885 | my $f = sub { |
| 886 | +{[]}; |
| 887 | } ; |
| 888 | #### |
| 889 | # anonconst |
| 890 | # CONTEXT no warnings 'experimental::const_attr'; |
| 891 | my $f = sub : const { |
| 892 | 123; |
| 893 | } |
| 894 | ; |
| 895 | #### |
| 896 | # bug #43010 |
| 897 | '!@$%'->(); |
| 898 | #### |
| 899 | # bug #43010 |
| 900 | ::(); |
| 901 | #### |
| 902 | # bug #43010 |
| 903 | '::::'->(); |
| 904 | #### |
| 905 | # bug #43010 |
| 906 | &::::; |
| 907 | #### |
| 908 | # [perl #77172] |
| 909 | package rt77172; |
| 910 | sub foo {} foo & & & foo; |
| 911 | >>>> |
| 912 | package rt77172; |
| 913 | foo(&{&} & foo()); |
| 914 | #### |
| 915 | # variables as method names |
| 916 | my $bar; |
| 917 | 'Foo'->$bar('orz'); |
| 918 | 'Foo'->$bar('orz') = 'a stranger stranger than before'; |
| 919 | #### |
| 920 | # constants as method names |
| 921 | 'Foo'->bar('orz'); |
| 922 | #### |
| 923 | # constants as method names without () |
| 924 | 'Foo'->bar; |
| 925 | #### |
| 926 | # [perl #47359] "indirect" method call notation |
| 927 | our @bar; |
| 928 | foo{@bar}+1,->foo; |
| 929 | (foo{@bar}+1),foo(); |
| 930 | foo{@bar}1 xor foo(); |
| 931 | >>>> |
| 932 | our @bar; |
| 933 | (foo { @bar } 1)->foo; |
| 934 | (foo { @bar } 1), foo(); |
| 935 | foo { @bar } 1 xor foo(); |
| 936 | #### |
| 937 | # indirops with blocks |
| 938 | # CONTEXT use 5.01; |
| 939 | print {*STDOUT;} 'foo'; |
| 940 | printf {*STDOUT;} 'foo'; |
| 941 | say {*STDOUT;} 'foo'; |
| 942 | system {'foo';} '-foo'; |
| 943 | exec {'foo';} '-foo'; |
| 944 | #### |
| 945 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 946 | # CONTEXT use feature ':5.10'; |
| 947 | # say |
| 948 | say 'foo'; |
| 949 | #### |
| 950 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 951 | # CONTEXT use 5.10.0; |
| 952 | # say in the context of use 5.10.0 |
| 953 | say 'foo'; |
| 954 | #### |
| 955 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 956 | # say with use 5.10.0 |
| 957 | use 5.10.0; |
| 958 | say 'foo'; |
| 959 | >>>> |
| 960 | no feature ':all'; |
| 961 | use feature ':5.10'; |
| 962 | say 'foo'; |
| 963 | #### |
| 964 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 965 | # say with use feature ':5.10'; |
| 966 | use feature ':5.10'; |
| 967 | say 'foo'; |
| 968 | >>>> |
| 969 | use feature 'say', 'state', 'switch'; |
| 970 | say 'foo'; |
| 971 | #### |
| 972 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 973 | # CONTEXT use feature ':5.10'; |
| 974 | # say with use 5.10.0 in the context of use feature |
| 975 | use 5.10.0; |
| 976 | say 'foo'; |
| 977 | >>>> |
| 978 | no feature ':all'; |
| 979 | use feature ':5.10'; |
| 980 | say 'foo'; |
| 981 | #### |
| 982 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
| 983 | # CONTEXT use 5.10.0; |
| 984 | # say with use feature ':5.10' in the context of use 5.10.0 |
| 985 | use feature ':5.10'; |
| 986 | say 'foo'; |
| 987 | >>>> |
| 988 | say 'foo'; |
| 989 | #### |
| 990 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 991 | # CONTEXT use feature ':5.15'; |
| 992 | # __SUB__ |
| 993 | __SUB__; |
| 994 | #### |
| 995 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 996 | # CONTEXT use 5.15.0; |
| 997 | # __SUB__ in the context of use 5.15.0 |
| 998 | __SUB__; |
| 999 | #### |
| 1000 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 1001 | # __SUB__ with use 5.15.0 |
| 1002 | use 5.15.0; |
| 1003 | __SUB__; |
| 1004 | >>>> |
| 1005 | no feature ':all'; |
| 1006 | use feature ':5.16'; |
| 1007 | __SUB__; |
| 1008 | #### |
| 1009 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 1010 | # __SUB__ with use feature ':5.15'; |
| 1011 | use feature ':5.15'; |
| 1012 | __SUB__; |
| 1013 | >>>> |
| 1014 | use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; |
| 1015 | __SUB__; |
| 1016 | #### |
| 1017 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 1018 | # CONTEXT use feature ':5.15'; |
| 1019 | # __SUB__ with use 5.15.0 in the context of use feature |
| 1020 | use 5.15.0; |
| 1021 | __SUB__; |
| 1022 | >>>> |
| 1023 | no feature ':all'; |
| 1024 | use feature ':5.16'; |
| 1025 | __SUB__; |
| 1026 | #### |
| 1027 | # SKIP ?$] < 5.015 && "__SUB__ not implemented on this Perl version" |
| 1028 | # CONTEXT use 5.15.0; |
| 1029 | # __SUB__ with use feature ':5.15' in the context of use 5.15.0 |
| 1030 | use feature ':5.15'; |
| 1031 | __SUB__; |
| 1032 | >>>> |
| 1033 | __SUB__; |
| 1034 | #### |
| 1035 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
| 1036 | # CONTEXT use feature ':5.10'; |
| 1037 | # state vars |
| 1038 | state $x = 42; |
| 1039 | #### |
| 1040 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
| 1041 | # CONTEXT use feature ':5.10'; |
| 1042 | # state var assignment |
| 1043 | { |
| 1044 | my $y = (state $x = 42); |
| 1045 | } |
| 1046 | #### |
| 1047 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
| 1048 | # CONTEXT use feature ':5.10'; |
| 1049 | # state vars in anonymous subroutines |
| 1050 | $a = sub { |
| 1051 | state $x; |
| 1052 | return $x++; |
| 1053 | } |
| 1054 | ; |
| 1055 | #### |
| 1056 | # SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version' |
| 1057 | # each @array; |
| 1058 | each @ARGV; |
| 1059 | each @$a; |
| 1060 | #### |
| 1061 | # SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version' |
| 1062 | # keys @array; values @array |
| 1063 | keys @$a if keys @ARGV; |
| 1064 | values @ARGV if values @$a; |
| 1065 | #### |
| 1066 | # Anonymous arrays and hashes, and references to them |
| 1067 | my $a = {}; |
| 1068 | my $b = \{}; |
| 1069 | my $c = []; |
| 1070 | my $d = \[]; |
| 1071 | #### |
| 1072 | # SKIP ?$] < 5.010 && "smartmatch and given/when not implemented on this Perl version" |
| 1073 | # CONTEXT use feature ':5.10'; no warnings 'deprecated'; |
| 1074 | # implicit smartmatch in given/when |
| 1075 | given ('foo') { |
| 1076 | when ('bar') { continue; } |
| 1077 | when ($_ ~~ 'quux') { continue; } |
| 1078 | default { 0; } |
| 1079 | } |
| 1080 | #### |
| 1081 | # conditions in elsifs (regression in change #33710 which fixed bug #37302) |
| 1082 | if ($a) { x(); } |
| 1083 | elsif ($b) { x(); } |
| 1084 | elsif ($a and $b) { x(); } |
| 1085 | elsif ($a or $b) { x(); } |
| 1086 | else { x(); } |
| 1087 | #### |
| 1088 | # interpolation in regexps |
| 1089 | my($y, $t); |
| 1090 | /x${y}z$t/; |
| 1091 | #### |
| 1092 | # TODO new undocumented cpan-bug #33708 |
| 1093 | # cpan-bug #33708 |
| 1094 | %{$_ || {}} |
| 1095 | #### |
| 1096 | # TODO hash constants not yet fixed |
| 1097 | # cpan-bug #33708 |
| 1098 | use constant H => { "#" => 1 }; H->{"#"} |
| 1099 | #### |
| 1100 | # TODO optimized away 0 not yet fixed |
| 1101 | # cpan-bug #33708 |
| 1102 | foreach my $i (@_) { 0 } |
| 1103 | #### |
| 1104 | # tests with not, not optimized |
| 1105 | my $c; |
| 1106 | x() unless $a; |
| 1107 | x() if not $a and $b; |
| 1108 | x() if $a and not $b; |
| 1109 | x() unless not $a and $b; |
| 1110 | x() unless $a and not $b; |
| 1111 | x() if not $a or $b; |
| 1112 | x() if $a or not $b; |
| 1113 | x() unless not $a or $b; |
| 1114 | x() unless $a or not $b; |
| 1115 | x() if $a and not $b and $c; |
| 1116 | x() if not $a and $b and not $c; |
| 1117 | x() unless $a and not $b and $c; |
| 1118 | x() unless not $a and $b and not $c; |
| 1119 | x() if $a or not $b or $c; |
| 1120 | x() if not $a or $b or not $c; |
| 1121 | x() unless $a or not $b or $c; |
| 1122 | x() unless not $a or $b or not $c; |
| 1123 | #### |
| 1124 | # tests with not, optimized |
| 1125 | my $c; |
| 1126 | x() if not $a; |
| 1127 | x() unless not $a; |
| 1128 | x() if not $a and not $b; |
| 1129 | x() unless not $a and not $b; |
| 1130 | x() if not $a or not $b; |
| 1131 | x() unless not $a or not $b; |
| 1132 | x() if not $a and not $b and $c; |
| 1133 | x() unless not $a and not $b and $c; |
| 1134 | x() if not $a or not $b or $c; |
| 1135 | x() unless not $a or not $b or $c; |
| 1136 | x() if not $a and not $b and not $c; |
| 1137 | x() unless not $a and not $b and not $c; |
| 1138 | x() if not $a or not $b or not $c; |
| 1139 | x() unless not $a or not $b or not $c; |
| 1140 | x() unless not $a or not $b or not $c; |
| 1141 | >>>> |
| 1142 | my $c; |
| 1143 | x() unless $a; |
| 1144 | x() if $a; |
| 1145 | x() unless $a or $b; |
| 1146 | x() if $a or $b; |
| 1147 | x() unless $a and $b; |
| 1148 | x() if $a and $b; |
| 1149 | x() if not $a || $b and $c; |
| 1150 | x() unless not $a || $b and $c; |
| 1151 | x() if not $a && $b or $c; |
| 1152 | x() unless not $a && $b or $c; |
| 1153 | x() unless $a or $b or $c; |
| 1154 | x() if $a or $b or $c; |
| 1155 | x() unless $a and $b and $c; |
| 1156 | x() if $a and $b and $c; |
| 1157 | x() unless not $a && $b && $c; |
| 1158 | #### |
| 1159 | # tests that should be constant folded |
| 1160 | x() if 1; |
| 1161 | x() if GLIPP; |
| 1162 | x() if !GLIPP; |
| 1163 | x() if GLIPP && GLIPP; |
| 1164 | x() if !GLIPP || GLIPP; |
| 1165 | x() if do { GLIPP }; |
| 1166 | x() if do { no warnings 'void'; 5; GLIPP }; |
| 1167 | x() if do { !GLIPP }; |
| 1168 | if (GLIPP) { x() } else { z() } |
| 1169 | if (!GLIPP) { x() } else { z() } |
| 1170 | if (GLIPP) { x() } elsif (GLIPP) { z() } |
| 1171 | if (!GLIPP) { x() } elsif (GLIPP) { z() } |
| 1172 | if (GLIPP) { x() } elsif (!GLIPP) { z() } |
| 1173 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } |
| 1174 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (GLIPP) { t() } |
| 1175 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() } |
| 1176 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() } |
| 1177 | >>>> |
| 1178 | x(); |
| 1179 | x(); |
| 1180 | '???'; |
| 1181 | x(); |
| 1182 | x(); |
| 1183 | x(); |
| 1184 | x(); |
| 1185 | do { |
| 1186 | '???' |
| 1187 | }; |
| 1188 | do { |
| 1189 | x() |
| 1190 | }; |
| 1191 | do { |
| 1192 | z() |
| 1193 | }; |
| 1194 | do { |
| 1195 | x() |
| 1196 | }; |
| 1197 | do { |
| 1198 | z() |
| 1199 | }; |
| 1200 | do { |
| 1201 | x() |
| 1202 | }; |
| 1203 | '???'; |
| 1204 | do { |
| 1205 | t() |
| 1206 | }; |
| 1207 | '???'; |
| 1208 | !1; |
| 1209 | #### |
| 1210 | # TODO constant deparsing has been backed out for 5.12 |
| 1211 | # XXXTODO ? $Config::Config{useithreads} && "doesn't work with threads" |
| 1212 | # tests that shouldn't be constant folded |
| 1213 | # It might be fundamentally impossible to make this work on ithreads, in which |
| 1214 | # case the TODO should become a SKIP |
| 1215 | x() if $a; |
| 1216 | if ($a == 1) { x() } elsif ($b == 2) { z() } |
| 1217 | if (do { foo(); GLIPP }) { x() } |
| 1218 | if (do { $a++; GLIPP }) { x() } |
| 1219 | >>>> |
| 1220 | x() if $a; |
| 1221 | if ($a == 1) { x(); } elsif ($b == 2) { z(); } |
| 1222 | if (do { foo(); GLIPP }) { x(); } |
| 1223 | if (do { ++$a; GLIPP }) { x(); } |
| 1224 | #### |
| 1225 | # TODO constant deparsing has been backed out for 5.12 |
| 1226 | # tests for deparsing constants |
| 1227 | warn PI; |
| 1228 | #### |
| 1229 | # TODO constant deparsing has been backed out for 5.12 |
| 1230 | # tests for deparsing imported constants |
| 1231 | warn O_TRUNC; |
| 1232 | #### |
| 1233 | # TODO constant deparsing has been backed out for 5.12 |
| 1234 | # tests for deparsing re-exported constants |
| 1235 | warn O_CREAT; |
| 1236 | #### |
| 1237 | # TODO constant deparsing has been backed out for 5.12 |
| 1238 | # tests for deparsing imported constants that got deleted from the original namespace |
| 1239 | warn O_APPEND; |
| 1240 | #### |
| 1241 | # TODO constant deparsing has been backed out for 5.12 |
| 1242 | # XXXTODO ? $Config::Config{useithreads} && "doesn't work with threads" |
| 1243 | # tests for deparsing constants which got turned into full typeglobs |
| 1244 | # It might be fundamentally impossible to make this work on ithreads, in which |
| 1245 | # case the TODO should become a SKIP |
| 1246 | warn O_EXCL; |
| 1247 | eval '@Fcntl::O_EXCL = qw/affe tiger/;'; |
| 1248 | warn O_EXCL; |
| 1249 | #### |
| 1250 | # TODO constant deparsing has been backed out for 5.12 |
| 1251 | # tests for deparsing of blessed constant with overloaded numification |
| 1252 | warn OVERLOADED_NUMIFICATION; |
| 1253 | #### |
| 1254 | # strict |
| 1255 | no strict; |
| 1256 | print $x; |
| 1257 | use strict 'vars'; |
| 1258 | print $main::x; |
| 1259 | use strict 'subs'; |
| 1260 | print $main::x; |
| 1261 | use strict 'refs'; |
| 1262 | print $main::x; |
| 1263 | no strict 'vars'; |
| 1264 | $x; |
| 1265 | #### |
| 1266 | # TODO Subsets of warnings could be encoded textually, rather than as bitflips. |
| 1267 | # subsets of warnings |
| 1268 | no warnings 'deprecated'; |
| 1269 | my $x; |
| 1270 | #### |
| 1271 | # TODO Better test for CPAN #33708 - the deparsed code has different behaviour |
| 1272 | # CPAN #33708 |
| 1273 | use strict; |
| 1274 | no warnings; |
| 1275 | |
| 1276 | foreach (0..3) { |
| 1277 | my $x = 2; |
| 1278 | { |
| 1279 | my $x if 0; |
| 1280 | print ++$x, "\n"; |
| 1281 | } |
| 1282 | } |
| 1283 | #### |
| 1284 | # no attribute list |
| 1285 | my $pi = 4; |
| 1286 | #### |
| 1287 | # SKIP ?$] > 5.013006 && ":= is now a syntax error" |
| 1288 | # := treated as an empty attribute list |
| 1289 | no warnings; |
| 1290 | my $pi := 4; |
| 1291 | >>>> |
| 1292 | no warnings; |
| 1293 | my $pi = 4; |
| 1294 | #### |
| 1295 | # : = empty attribute list |
| 1296 | my $pi : = 4; |
| 1297 | >>>> |
| 1298 | my $pi = 4; |
| 1299 | #### |
| 1300 | # in place sort |
| 1301 | our @a; |
| 1302 | my @b; |
| 1303 | @a = sort @a; |
| 1304 | @b = sort @b; |
| 1305 | (); |
| 1306 | #### |
| 1307 | # in place reverse |
| 1308 | our @a; |
| 1309 | my @b; |
| 1310 | @a = reverse @a; |
| 1311 | @b = reverse @b; |
| 1312 | (); |
| 1313 | #### |
| 1314 | # #71870 Use of uninitialized value in bitwise and B::Deparse |
| 1315 | my($r, $s, @a); |
| 1316 | @a = split(/foo/, $s, 0); |
| 1317 | $r = qr/foo/; |
| 1318 | @a = split(/$r/, $s, 0); |
| 1319 | (); |
| 1320 | #### |
| 1321 | # package declaration before label |
| 1322 | { |
| 1323 | package Foo; |
| 1324 | label: print 123; |
| 1325 | } |
| 1326 | #### |
| 1327 | # shift optimisation |
| 1328 | shift; |
| 1329 | >>>> |
| 1330 | shift(); |
| 1331 | #### |
| 1332 | # shift optimisation |
| 1333 | shift @_; |
| 1334 | #### |
| 1335 | # shift optimisation |
| 1336 | pop; |
| 1337 | >>>> |
| 1338 | pop(); |
| 1339 | #### |
| 1340 | # shift optimisation |
| 1341 | pop @_; |
| 1342 | #### |
| 1343 | #[perl #20444] |
| 1344 | "foo" =~ (1 ? /foo/ : /bar/); |
| 1345 | "foo" =~ (1 ? y/foo// : /bar/); |
| 1346 | "foo" =~ (1 ? y/foo//r : /bar/); |
| 1347 | "foo" =~ (1 ? s/foo// : /bar/); |
| 1348 | >>>> |
| 1349 | 'foo' =~ ($_ =~ /foo/); |
| 1350 | 'foo' =~ ($_ =~ tr/fo//); |
| 1351 | 'foo' =~ ($_ =~ tr/fo//r); |
| 1352 | 'foo' =~ ($_ =~ s/foo//); |
| 1353 | #### |
| 1354 | # The fix for [perl #20444] broke this. |
| 1355 | 'foo' =~ do { () }; |
| 1356 | #### |
| 1357 | # [perl #81424] match against aelemfast_lex |
| 1358 | my @s; |
| 1359 | print /$s[1]/; |
| 1360 | #### |
| 1361 | # /$#a/ |
| 1362 | print /$#main::a/; |
| 1363 | #### |
| 1364 | # /@array/ |
| 1365 | our @a; |
| 1366 | my @b; |
| 1367 | print /@a/; |
| 1368 | print /@b/; |
| 1369 | print qr/@a/; |
| 1370 | print qr/@b/; |
| 1371 | #### |
| 1372 | # =~ QR_CONSTANT |
| 1373 | use constant QR_CONSTANT => qr/a/soupmix; |
| 1374 | '' =~ QR_CONSTANT; |
| 1375 | >>>> |
| 1376 | '' =~ /a/impsux; |
| 1377 | #### |
| 1378 | # $lexical =~ // |
| 1379 | my $x; |
| 1380 | $x =~ //; |
| 1381 | #### |
| 1382 | # [perl #91318] /regexp/applaud |
| 1383 | print /a/a, s/b/c/a; |
| 1384 | print /a/aa, s/b/c/aa; |
| 1385 | print /a/p, s/b/c/p; |
| 1386 | print /a/l, s/b/c/l; |
| 1387 | print /a/u, s/b/c/u; |
| 1388 | { |
| 1389 | use feature "unicode_strings"; |
| 1390 | print /a/d, s/b/c/d; |
| 1391 | } |
| 1392 | { |
| 1393 | use re "/u"; |
| 1394 | print /a/d, s/b/c/d; |
| 1395 | } |
| 1396 | { |
| 1397 | use 5.012; |
| 1398 | print /a/d, s/b/c/d; |
| 1399 | } |
| 1400 | >>>> |
| 1401 | print /a/a, s/b/c/a; |
| 1402 | print /a/aa, s/b/c/aa; |
| 1403 | print /a/p, s/b/c/p; |
| 1404 | print /a/l, s/b/c/l; |
| 1405 | print /a/u, s/b/c/u; |
| 1406 | { |
| 1407 | use feature 'unicode_strings'; |
| 1408 | print /a/d, s/b/c/d; |
| 1409 | } |
| 1410 | { |
| 1411 | BEGIN { $^H{'reflags'} = '0'; |
| 1412 | $^H{'reflags_charset'} = '2'; } |
| 1413 | print /a/d, s/b/c/d; |
| 1414 | } |
| 1415 | { |
| 1416 | no feature ':all'; |
| 1417 | use feature ':5.12'; |
| 1418 | print /a/d, s/b/c/d; |
| 1419 | } |
| 1420 | #### |
| 1421 | # all the flags (qr//) |
| 1422 | $_ = qr/X/m; |
| 1423 | $_ = qr/X/s; |
| 1424 | $_ = qr/X/i; |
| 1425 | $_ = qr/X/x; |
| 1426 | $_ = qr/X/p; |
| 1427 | $_ = qr/X/o; |
| 1428 | $_ = qr/X/u; |
| 1429 | $_ = qr/X/a; |
| 1430 | $_ = qr/X/l; |
| 1431 | $_ = qr/X/n; |
| 1432 | #### |
| 1433 | use feature 'unicode_strings'; |
| 1434 | $_ = qr/X/d; |
| 1435 | #### |
| 1436 | # all the flags (m//) |
| 1437 | /X/m; |
| 1438 | /X/s; |
| 1439 | /X/i; |
| 1440 | /X/x; |
| 1441 | /X/p; |
| 1442 | /X/o; |
| 1443 | /X/u; |
| 1444 | /X/a; |
| 1445 | /X/l; |
| 1446 | /X/n; |
| 1447 | /X/g; |
| 1448 | /X/cg; |
| 1449 | #### |
| 1450 | use feature 'unicode_strings'; |
| 1451 | /X/d; |
| 1452 | #### |
| 1453 | # all the flags (s///) |
| 1454 | s/X//m; |
| 1455 | s/X//s; |
| 1456 | s/X//i; |
| 1457 | s/X//x; |
| 1458 | s/X//p; |
| 1459 | s/X//o; |
| 1460 | s/X//u; |
| 1461 | s/X//a; |
| 1462 | s/X//l; |
| 1463 | s/X//n; |
| 1464 | s/X//g; |
| 1465 | s/X/'';/e; |
| 1466 | s/X//r; |
| 1467 | #### |
| 1468 | use feature 'unicode_strings'; |
| 1469 | s/X//d; |
| 1470 | #### |
| 1471 | # tr/// with all the flags: empty replacement |
| 1472 | tr/B-G//; |
| 1473 | tr/B-G//c; |
| 1474 | tr/B-G//d; |
| 1475 | tr/B-G//s; |
| 1476 | tr/B-G//cd; |
| 1477 | tr/B-G//ds; |
| 1478 | tr/B-G//cs; |
| 1479 | tr/B-G//cds; |
| 1480 | tr/B-G//r; |
| 1481 | #### |
| 1482 | # tr/// with all the flags: short replacement |
| 1483 | tr/B-G/b/; |
| 1484 | tr/B-G/b/c; |
| 1485 | tr/B-G/b/d; |
| 1486 | tr/B-G/b/s; |
| 1487 | tr/B-G/b/cd; |
| 1488 | tr/B-G/b/ds; |
| 1489 | tr/B-G/b/cs; |
| 1490 | tr/B-G/b/cds; |
| 1491 | tr/B-G/b/r; |
| 1492 | #### |
| 1493 | # tr/// with all the flags: equal length replacement |
| 1494 | tr/B-G/b-g/; |
| 1495 | tr/B-G/b-g/c; |
| 1496 | tr/B-G/b-g/s; |
| 1497 | tr/B-G/b-g/cs; |
| 1498 | tr/B-G/b-g/r; |
| 1499 | #### |
| 1500 | # tr with extended table (/c) |
| 1501 | tr/\000-\375/AB/c; |
| 1502 | tr/\000-\375/A-C/c; |
| 1503 | tr/\000-\375/A-D/c; |
| 1504 | tr/\000-\375/A-I/c; |
| 1505 | tr/\000-\375/AB/cd; |
| 1506 | tr/\000-\375/A-C/cd; |
| 1507 | tr/\000-\375/A-D/cd; |
| 1508 | tr/\000-\375/A-I/cd; |
| 1509 | tr/\000-\375/AB/cds; |
| 1510 | tr/\000-\375/A-C/cds; |
| 1511 | tr/\000-\375/A-D/cds; |
| 1512 | tr/\000-\375/A-I/cds; |
| 1513 | #### |
| 1514 | # tr/// with all the flags: empty replacement |
| 1515 | tr/\x{101}-\x{106}//; |
| 1516 | tr/\x{101}-\x{106}//c; |
| 1517 | tr/\x{101}-\x{106}//d; |
| 1518 | tr/\x{101}-\x{106}//s; |
| 1519 | tr/\x{101}-\x{106}//cd; |
| 1520 | tr/\x{101}-\x{106}//ds; |
| 1521 | tr/\x{101}-\x{106}//cs; |
| 1522 | tr/\x{101}-\x{106}//cds; |
| 1523 | tr/\x{101}-\x{106}//r; |
| 1524 | #### |
| 1525 | # tr/// with all the flags: short replacement |
| 1526 | tr/\x{101}-\x{106}/\x{111}/; |
| 1527 | tr/\x{101}-\x{106}/\x{111}/c; |
| 1528 | tr/\x{101}-\x{106}/\x{111}/d; |
| 1529 | tr/\x{101}-\x{106}/\x{111}/s; |
| 1530 | tr/\x{101}-\x{106}/\x{111}/cd; |
| 1531 | tr/\x{101}-\x{106}/\x{111}/ds; |
| 1532 | tr/\x{101}-\x{106}/\x{111}/cs; |
| 1533 | tr/\x{101}-\x{106}/\x{111}/cds; |
| 1534 | tr/\x{101}-\x{106}/\x{111}/r; |
| 1535 | #### |
| 1536 | # tr/// with all the flags: equal length replacement |
| 1537 | tr/\x{101}-\x{106}/\x{111}-\x{116}/; |
| 1538 | tr/\x{101}-\x{106}/\x{111}-\x{116}/c; |
| 1539 | tr/\x{101}-\x{106}/\x{111}-\x{116}/s; |
| 1540 | tr/\x{101}-\x{106}/\x{111}-\x{116}/cs; |
| 1541 | tr/\x{101}-\x{106}/\x{111}-\x{116}/r; |
| 1542 | #### |
| 1543 | # tr across 255/256 boundary, complemented |
| 1544 | tr/\cA-\x{100}/AB/c; |
| 1545 | tr/\cA-\x{100}/A-C/c; |
| 1546 | tr/\cA-\x{100}/A-D/c; |
| 1547 | tr/\cA-\x{100}/A-I/c; |
| 1548 | tr/\cA-\x{100}/AB/cd; |
| 1549 | tr/\cA-\x{100}/A-C/cd; |
| 1550 | tr/\cA-\x{100}/A-D/cd; |
| 1551 | tr/\cA-\x{100}/A-I/cd; |
| 1552 | tr/\cA-\x{100}/AB/cds; |
| 1553 | tr/\cA-\x{100}/A-C/cds; |
| 1554 | tr/\cA-\x{100}/A-D/cds; |
| 1555 | tr/\cA-\x{100}/A-I/cds; |
| 1556 | #### |
| 1557 | # [perl #119807] s//\(3)/ge should not warn when deparsed (\3 warns) |
| 1558 | s/foo/\(3);/eg; |
| 1559 | #### |
| 1560 | # [perl #115256] |
| 1561 | "" =~ /a(?{ print q| |
| 1562 | |})/; |
| 1563 | >>>> |
| 1564 | '' =~ /a(?{ print "\n"; })/; |
| 1565 | #### |
| 1566 | # [perl #123217] |
| 1567 | $_ = qr/(??{<<END})/ |
| 1568 | f.o |
| 1569 | b.r |
| 1570 | END |
| 1571 | >>>> |
| 1572 | $_ = qr/(??{ "f.o\nb.r\n"; })/; |
| 1573 | #### |
| 1574 | # More regexp code block madness |
| 1575 | my($b, @a); |
| 1576 | /(?{ die $b; })/; |
| 1577 | /a(?{ die $b; })a/; |
| 1578 | /$a(?{ die $b; })/; |
| 1579 | /@a(?{ die $b; })/; |
| 1580 | /(??{ die $b; })/; |
| 1581 | /a(??{ die $b; })a/; |
| 1582 | /$a(??{ die $b; })/; |
| 1583 | /@a(??{ die $b; })/; |
| 1584 | qr/(?{ die $b; })/; |
| 1585 | qr/a(?{ die $b; })a/; |
| 1586 | qr/$a(?{ die $b; })/; |
| 1587 | qr/@a(?{ die $b; })/; |
| 1588 | qr/(??{ die $b; })/; |
| 1589 | qr/a(??{ die $b; })a/; |
| 1590 | qr/$a(??{ die $b; })/; |
| 1591 | qr/@a(??{ die $b; })/; |
| 1592 | s/(?{ die $b; })//; |
| 1593 | s/a(?{ die $b; })a//; |
| 1594 | s/$a(?{ die $b; })//; |
| 1595 | s/@a(?{ die $b; })//; |
| 1596 | s/(??{ die $b; })//; |
| 1597 | s/a(??{ die $b; })a//; |
| 1598 | s/$a(??{ die $b; })//; |
| 1599 | s/@a(??{ die $b; })//; |
| 1600 | #### |
| 1601 | # /(?x)<newline><tab>/ |
| 1602 | /(?x) |
| 1603 | /; |
| 1604 | #### |
| 1605 | # y///r |
| 1606 | tr/a/b/r + $a =~ tr/p/q/r; |
| 1607 | #### |
| 1608 | # y///d in list [perl #119815] |
| 1609 | () = tr/a//d; |
| 1610 | #### |
| 1611 | # [perl #90898] |
| 1612 | <a,>; |
| 1613 | glob 'a,'; |
| 1614 | >>>> |
| 1615 | glob 'a,'; |
| 1616 | glob 'a,'; |
| 1617 | #### |
| 1618 | # [perl #91008] |
| 1619 | # SKIP ?$] >= 5.023 && "autoderef deleted in this Perl version" |
| 1620 | # CONTEXT no warnings 'experimental::autoderef'; |
| 1621 | each $@; |
| 1622 | keys $~; |
| 1623 | values $!; |
| 1624 | #### |
| 1625 | # readpipe with complex expression |
| 1626 | readpipe $a + $b; |
| 1627 | #### |
| 1628 | # aelemfast |
| 1629 | $b::a[0] = 1; |
| 1630 | #### |
| 1631 | # aelemfast for a lexical |
| 1632 | my @a; |
| 1633 | $a[0] = 1; |
| 1634 | #### |
| 1635 | # feature features without feature |
| 1636 | # CONTEXT no warnings 'deprecated'; |
| 1637 | CORE::state $x; |
| 1638 | CORE::say $x; |
| 1639 | CORE::given ($x) { |
| 1640 | CORE::when (3) { |
| 1641 | continue; |
| 1642 | } |
| 1643 | CORE::default { |
| 1644 | CORE::break; |
| 1645 | } |
| 1646 | } |
| 1647 | CORE::evalbytes ''; |
| 1648 | () = CORE::__SUB__; |
| 1649 | () = CORE::fc $x; |
| 1650 | #### |
| 1651 | # feature features when feature has been disabled by use VERSION |
| 1652 | # CONTEXT no warnings 'deprecated'; |
| 1653 | use feature (sprintf(":%vd", $^V)); |
| 1654 | use 1; |
| 1655 | CORE::say $_; |
| 1656 | CORE::state $x; |
| 1657 | CORE::given ($x) { |
| 1658 | CORE::when (3) { |
| 1659 | continue; |
| 1660 | } |
| 1661 | CORE::default { |
| 1662 | CORE::break; |
| 1663 | } |
| 1664 | } |
| 1665 | CORE::evalbytes ''; |
| 1666 | () = CORE::__SUB__; |
| 1667 | >>>> |
| 1668 | CORE::say $_; |
| 1669 | CORE::state $x; |
| 1670 | CORE::given ($x) { |
| 1671 | CORE::when (3) { |
| 1672 | continue; |
| 1673 | } |
| 1674 | CORE::default { |
| 1675 | CORE::break; |
| 1676 | } |
| 1677 | } |
| 1678 | CORE::evalbytes ''; |
| 1679 | () = CORE::__SUB__; |
| 1680 | #### |
| 1681 | # (the above test with CONTEXT, and the output is equivalent but different) |
| 1682 | # CONTEXT use feature ':5.10'; no warnings 'deprecated'; |
| 1683 | # feature features when feature has been disabled by use VERSION |
| 1684 | use feature (sprintf(":%vd", $^V)); |
| 1685 | use 1; |
| 1686 | CORE::say $_; |
| 1687 | CORE::state $x; |
| 1688 | CORE::given ($x) { |
| 1689 | CORE::when (3) { |
| 1690 | continue; |
| 1691 | } |
| 1692 | CORE::default { |
| 1693 | CORE::break; |
| 1694 | } |
| 1695 | } |
| 1696 | CORE::evalbytes ''; |
| 1697 | () = CORE::__SUB__; |
| 1698 | >>>> |
| 1699 | no feature ':all'; |
| 1700 | use feature ':default'; |
| 1701 | CORE::say $_; |
| 1702 | CORE::state $x; |
| 1703 | CORE::given ($x) { |
| 1704 | CORE::when (3) { |
| 1705 | continue; |
| 1706 | } |
| 1707 | CORE::default { |
| 1708 | CORE::break; |
| 1709 | } |
| 1710 | } |
| 1711 | CORE::evalbytes ''; |
| 1712 | () = CORE::__SUB__; |
| 1713 | #### |
| 1714 | # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version" |
| 1715 | # lexical subroutines and keywords of the same name |
| 1716 | # CONTEXT use feature 'lexical_subs', 'switch'; no warnings 'experimental'; no warnings 'deprecated'; |
| 1717 | my sub default; |
| 1718 | my sub else; |
| 1719 | my sub elsif; |
| 1720 | my sub for; |
| 1721 | my sub foreach; |
| 1722 | my sub given; |
| 1723 | my sub if; |
| 1724 | my sub m; |
| 1725 | my sub no; |
| 1726 | my sub package; |
| 1727 | my sub q; |
| 1728 | my sub qq; |
| 1729 | my sub qr; |
| 1730 | my sub qx; |
| 1731 | my sub require; |
| 1732 | my sub s; |
| 1733 | my sub sub; |
| 1734 | my sub tr; |
| 1735 | my sub unless; |
| 1736 | my sub until; |
| 1737 | my sub use; |
| 1738 | my sub when; |
| 1739 | my sub while; |
| 1740 | CORE::default { die; } |
| 1741 | CORE::if ($1) { die; } |
| 1742 | CORE::if ($1) { die; } |
| 1743 | CORE::elsif ($1) { die; } |
| 1744 | CORE::else { die; } |
| 1745 | CORE::for (die; $1; die) { die; } |
| 1746 | CORE::foreach $_ (1 .. 10) { die; } |
| 1747 | die CORE::foreach (1); |
| 1748 | CORE::given ($1) { die; } |
| 1749 | CORE::m[/]; |
| 1750 | CORE::m?/?; |
| 1751 | CORE::package foo; |
| 1752 | CORE::no strict; |
| 1753 | () = (CORE::q['], CORE::qq["$_], CORE::qr//, CORE::qx[`]); |
| 1754 | CORE::require 1; |
| 1755 | CORE::s///; |
| 1756 | () = CORE::sub { die; } ; |
| 1757 | CORE::tr///; |
| 1758 | CORE::unless ($1) { die; } |
| 1759 | CORE::until ($1) { die; } |
| 1760 | die CORE::until $1; |
| 1761 | CORE::use strict; |
| 1762 | CORE::when ($1 ~~ $2) { die; } |
| 1763 | CORE::while ($1) { die; } |
| 1764 | die CORE::while $1; |
| 1765 | #### |
| 1766 | # Feature hints |
| 1767 | use feature 'current_sub', 'evalbytes'; |
| 1768 | print; |
| 1769 | use 1; |
| 1770 | print; |
| 1771 | use 5.014; |
| 1772 | print; |
| 1773 | no feature 'unicode_strings'; |
| 1774 | print; |
| 1775 | >>>> |
| 1776 | use feature 'current_sub', 'evalbytes'; |
| 1777 | print $_; |
| 1778 | no feature ':all'; |
| 1779 | use feature ':default'; |
| 1780 | print $_; |
| 1781 | no feature ':all'; |
| 1782 | use feature ':5.12'; |
| 1783 | print $_; |
| 1784 | no feature 'unicode_strings'; |
| 1785 | print $_; |
| 1786 | #### |
| 1787 | # $#- $#+ $#{%} etc. |
| 1788 | my @x; |
| 1789 | @x = ($#{`}, $#{~}, $#{!}, $#{@}, $#{$}, $#{%}, $#{^}, $#{&}, $#{*}); |
| 1790 | @x = ($#{(}, $#{)}, $#{[}, $#{{}, $#{]}, $#{}}, $#{'}, $#{"}, $#{,}); |
| 1791 | @x = ($#{<}, $#{.}, $#{>}, $#{/}, $#{?}, $#{=}, $#+, $#{\}, $#{|}, $#-); |
| 1792 | @x = ($#{;}, $#{:}, $#{1}), $#_; |
| 1793 | #### |
| 1794 | # [perl #86060] $( $| $) in regexps need braces |
| 1795 | /${(}/; |
| 1796 | /${|}/; |
| 1797 | /${)}/; |
| 1798 | /${(}${|}${)}/; |
| 1799 | /@{+}@{-}/; |
| 1800 | #### |
| 1801 | # ()[...] |
| 1802 | my(@a) = ()[()]; |
| 1803 | #### |
| 1804 | # sort(foo(bar)) |
| 1805 | # sort(foo(bar)) is interpreted as sort &foo(bar) |
| 1806 | # sort foo(bar) is interpreted as sort foo bar |
| 1807 | # parentheses are not optional in this case |
| 1808 | print sort(foo('bar')); |
| 1809 | >>>> |
| 1810 | print sort(foo('bar')); |
| 1811 | #### |
| 1812 | # substr assignment |
| 1813 | substr(my $a, 0, 0) = (foo(), bar()); |
| 1814 | $a++; |
| 1815 | #### |
| 1816 | # This following line works around an unfixed bug that we are not trying to |
| 1817 | # test for here: |
| 1818 | # CONTEXT BEGIN { $^H{a} = "b"; delete $^H{a} } # make %^H localised |
| 1819 | # hint hash |
| 1820 | BEGIN { $^H{'foo'} = undef; } |
| 1821 | { |
| 1822 | BEGIN { $^H{'bar'} = undef; } |
| 1823 | { |
| 1824 | BEGIN { $^H{'baz'} = undef; } |
| 1825 | { |
| 1826 | print $_; |
| 1827 | } |
| 1828 | print $_; |
| 1829 | } |
| 1830 | print $_; |
| 1831 | } |
| 1832 | BEGIN { $^H{q[']} = '('; } |
| 1833 | print $_; |
| 1834 | #### |
| 1835 | # This following line works around an unfixed bug that we are not trying to |
| 1836 | # test for here: |
| 1837 | # CONTEXT BEGIN { $^H{a} = "b"; delete $^H{a} } # make %^H localised |
| 1838 | # hint hash changes that serialise the same way with sort %hh |
| 1839 | BEGIN { $^H{'a'} = 'b'; } |
| 1840 | { |
| 1841 | BEGIN { $^H{'b'} = 'a'; delete $^H{'a'}; } |
| 1842 | print $_; |
| 1843 | } |
| 1844 | print $_; |
| 1845 | #### |
| 1846 | # [perl #47361] do({}) and do +{} (variants of do-file) |
| 1847 | do({}); |
| 1848 | do +{}; |
| 1849 | sub foo::do {} |
| 1850 | package foo; |
| 1851 | CORE::do({}); |
| 1852 | CORE::do +{}; |
| 1853 | >>>> |
| 1854 | do({}); |
| 1855 | do({}); |
| 1856 | package foo; |
| 1857 | CORE::do({}); |
| 1858 | CORE::do({}); |
| 1859 | #### |
| 1860 | # [perl #77096] functions that do not follow the looks-like-a-function rule |
| 1861 | () = (return 1) + time; |
| 1862 | () = (return ($1 + $2) * $3) + time; |
| 1863 | () = (return ($a xor $b)) + time; |
| 1864 | () = (do 'file') + time; |
| 1865 | () = (do ($1 + $2) * $3) + time; |
| 1866 | () = (do ($1 xor $2)) + time; |
| 1867 | () = (goto 1) + 3; |
| 1868 | () = (require 'foo') + 3; |
| 1869 | () = (require foo) + 3; |
| 1870 | () = (CORE::dump 1) + 3; |
| 1871 | () = (last 1) + 3; |
| 1872 | () = (next 1) + 3; |
| 1873 | () = (redo 1) + 3; |
| 1874 | () = (-R $_) + 3; |
| 1875 | () = (-W $_) + 3; |
| 1876 | () = (-X $_) + 3; |
| 1877 | () = (-r $_) + 3; |
| 1878 | () = (-w $_) + 3; |
| 1879 | () = (-x $_) + 3; |
| 1880 | >>>> |
| 1881 | () = (return 1); |
| 1882 | () = (return ($1 + $2) * $3); |
| 1883 | () = (return ($a xor $b)); |
| 1884 | () = (do 'file') + time; |
| 1885 | () = (do ($1 + $2) * $3) + time; |
| 1886 | () = (do ($1 xor $2)) + time; |
| 1887 | () = (goto 1); |
| 1888 | () = (require 'foo') + 3; |
| 1889 | () = (require foo) + 3; |
| 1890 | () = (CORE::dump 1); |
| 1891 | () = (last 1); |
| 1892 | () = (next 1); |
| 1893 | () = (redo 1); |
| 1894 | () = (-R $_) + 3; |
| 1895 | () = (-W $_) + 3; |
| 1896 | () = (-X $_) + 3; |
| 1897 | () = (-r $_) + 3; |
| 1898 | () = (-w $_) + 3; |
| 1899 | () = (-x $_) + 3; |
| 1900 | #### |
| 1901 | # require(foo()) and do(foo()) |
| 1902 | require (foo()); |
| 1903 | do (foo()); |
| 1904 | goto (foo()); |
| 1905 | CORE::dump (foo()); |
| 1906 | last (foo()); |
| 1907 | next (foo()); |
| 1908 | redo (foo()); |
| 1909 | #### |
| 1910 | # require vstring |
| 1911 | require v5.16; |
| 1912 | #### |
| 1913 | # [perl #97476] not() *does* follow the llafr |
| 1914 | $_ = ($a xor not +($1 || 2) ** 2); |
| 1915 | #### |
| 1916 | # Precedence conundrums with argument-less function calls |
| 1917 | () = (eof) + 1; |
| 1918 | () = (return) + 1; |
| 1919 | () = (return, 1); |
| 1920 | () = warn; |
| 1921 | () = warn() + 1; |
| 1922 | () = setpgrp() + 1; |
| 1923 | >>>> |
| 1924 | () = (eof) + 1; |
| 1925 | () = (return); |
| 1926 | () = (return, 1); |
| 1927 | () = warn; |
| 1928 | () = warn() + 1; |
| 1929 | () = setpgrp() + 1; |
| 1930 | #### |
| 1931 | # loopexes have assignment prec |
| 1932 | () = (CORE::dump a) | 'b'; |
| 1933 | () = (goto a) | 'b'; |
| 1934 | () = (last a) | 'b'; |
| 1935 | () = (next a) | 'b'; |
| 1936 | () = (redo a) | 'b'; |
| 1937 | >>>> |
| 1938 | () = (CORE::dump a); |
| 1939 | () = (goto a); |
| 1940 | () = (last a); |
| 1941 | () = (next a); |
| 1942 | () = (redo a); |
| 1943 | #### |
| 1944 | # [perl #63558] open local(*FH) |
| 1945 | open local *FH; |
| 1946 | pipe local *FH, local *FH; |
| 1947 | #### |
| 1948 | # [perl #91416] open "string" |
| 1949 | open 'open'; |
| 1950 | open '####'; |
| 1951 | open '^A'; |
| 1952 | open "\ca"; |
| 1953 | >>>> |
| 1954 | open *open; |
| 1955 | open '####'; |
| 1956 | open '^A'; |
| 1957 | open *^A; |
| 1958 | #### |
| 1959 | # "string"->[] ->{} |
| 1960 | no strict 'vars'; |
| 1961 | () = 'open'->[0]; #aelemfast |
| 1962 | () = '####'->[0]; |
| 1963 | () = '^A'->[0]; |
| 1964 | () = "\ca"->[0]; |
| 1965 | () = 'a::]b'->[0]; |
| 1966 | () = 'open'->[$_]; #aelem |
| 1967 | () = '####'->[$_]; |
| 1968 | () = '^A'->[$_]; |
| 1969 | () = "\ca"->[$_]; |
| 1970 | () = 'a::]b'->[$_]; |
| 1971 | () = 'open'->{0}; #helem |
| 1972 | () = '####'->{0}; |
| 1973 | () = '^A'->{0}; |
| 1974 | () = "\ca"->{0}; |
| 1975 | () = 'a::]b'->{0}; |
| 1976 | >>>> |
| 1977 | no strict 'vars'; |
| 1978 | () = $open[0]; |
| 1979 | () = '####'->[0]; |
| 1980 | () = '^A'->[0]; |
| 1981 | () = $^A[0]; |
| 1982 | () = 'a::]b'->[0]; |
| 1983 | () = $open[$_]; |
| 1984 | () = '####'->[$_]; |
| 1985 | () = '^A'->[$_]; |
| 1986 | () = $^A[$_]; |
| 1987 | () = 'a::]b'->[$_]; |
| 1988 | () = $open{'0'}; |
| 1989 | () = '####'->{'0'}; |
| 1990 | () = '^A'->{'0'}; |
| 1991 | () = $^A{'0'}; |
| 1992 | () = 'a::]b'->{'0'}; |
| 1993 | #### |
| 1994 | # [perl #74740] -(f()) vs -f() |
| 1995 | $_ = -(f()); |
| 1996 | #### |
| 1997 | # require <binop> |
| 1998 | require 'a' . $1; |
| 1999 | #### |
| 2000 | #[perl #30504] foreach-my postfix/prefix difference |
| 2001 | $_ = 'foo' foreach my ($foo1, $bar1, $baz1); |
| 2002 | foreach (my ($foo2, $bar2, $baz2)) { $_ = 'foo' } |
| 2003 | foreach my $i (my ($foo3, $bar3, $baz3)) { $i = 'foo' } |
| 2004 | >>>> |
| 2005 | $_ = 'foo' foreach (my($foo1, $bar1, $baz1)); |
| 2006 | foreach $_ (my($foo2, $bar2, $baz2)) { |
| 2007 | $_ = 'foo'; |
| 2008 | } |
| 2009 | foreach my $i (my($foo3, $bar3, $baz3)) { |
| 2010 | $i = 'foo'; |
| 2011 | } |
| 2012 | #### |
| 2013 | #[perl #108224] foreach with continue block |
| 2014 | foreach (1 .. 3) { print } continue { print "\n" } |
| 2015 | foreach (1 .. 3) { } continue { } |
| 2016 | foreach my $i (1 .. 3) { print $i } continue { print "\n" } |
| 2017 | foreach my $i (1 .. 3) { } continue { } |
| 2018 | >>>> |
| 2019 | foreach $_ (1 .. 3) { |
| 2020 | print $_; |
| 2021 | } |
| 2022 | continue { |
| 2023 | print "\n"; |
| 2024 | } |
| 2025 | foreach $_ (1 .. 3) { |
| 2026 | (); |
| 2027 | } |
| 2028 | continue { |
| 2029 | (); |
| 2030 | } |
| 2031 | foreach my $i (1 .. 3) { |
| 2032 | print $i; |
| 2033 | } |
| 2034 | continue { |
| 2035 | print "\n"; |
| 2036 | } |
| 2037 | foreach my $i (1 .. 3) { |
| 2038 | (); |
| 2039 | } |
| 2040 | continue { |
| 2041 | (); |
| 2042 | } |
| 2043 | #### |
| 2044 | # file handles |
| 2045 | no strict; |
| 2046 | my $mfh; |
| 2047 | open F; |
| 2048 | open *F; |
| 2049 | open $fh; |
| 2050 | open $mfh; |
| 2051 | open 'a+b'; |
| 2052 | select *F; |
| 2053 | select F; |
| 2054 | select $f; |
| 2055 | select $mfh; |
| 2056 | select 'a+b'; |
| 2057 | #### |
| 2058 | # 'my' works with padrange op |
| 2059 | my($z, @z); |
| 2060 | my $m1; |
| 2061 | $m1 = 1; |
| 2062 | $z = $m1; |
| 2063 | my $m2 = 2; |
| 2064 | my($m3, $m4); |
| 2065 | ($m3, $m4) = (1, 2); |
| 2066 | @z = ($m3, $m4); |
| 2067 | my($m5, $m6) = (1, 2); |
| 2068 | my($m7, undef, $m8) = (1, 2, 3); |
| 2069 | @z = ($m7, undef, $m8); |
| 2070 | ($m7, undef, $m8) = (1, 2, 3); |
| 2071 | #### |
| 2072 | # 'our/local' works with padrange op |
| 2073 | our($z, @z); |
| 2074 | our $o1; |
| 2075 | no strict; |
| 2076 | local $o11; |
| 2077 | $o1 = 1; |
| 2078 | local $o1 = 1; |
| 2079 | $z = $o1; |
| 2080 | $z = local $o1; |
| 2081 | our $o2 = 2; |
| 2082 | our($o3, $o4); |
| 2083 | ($o3, $o4) = (1, 2); |
| 2084 | local($o3, $o4) = (1, 2); |
| 2085 | @z = ($o3, $o4); |
| 2086 | @z = local($o3, $o4); |
| 2087 | our($o5, $o6) = (1, 2); |
| 2088 | our($o7, undef, $o8) = (1, 2, 3); |
| 2089 | @z = ($o7, undef, $o8); |
| 2090 | @z = local($o7, undef, $o8); |
| 2091 | ($o7, undef, $o8) = (1, 2, 3); |
| 2092 | local($o7, undef, $o8) = (1, 2, 3); |
| 2093 | #### |
| 2094 | # 'state' works with padrange op |
| 2095 | # CONTEXT no strict; use feature 'state'; |
| 2096 | state($z, @z); |
| 2097 | state $s1; |
| 2098 | $s1 = 1; |
| 2099 | $z = $s1; |
| 2100 | state $s2 = 2; |
| 2101 | state($s3, $s4); |
| 2102 | ($s3, $s4) = (1, 2); |
| 2103 | @z = ($s3, $s4); |
| 2104 | # assignment of state lists isn't implemented yet |
| 2105 | #state($s5, $s6) = (1, 2); |
| 2106 | #state($s7, undef, $s8) = (1, 2, 3); |
| 2107 | #@z = ($s7, undef, $s8); |
| 2108 | ($s7, undef, $s8) = (1, 2, 3); |
| 2109 | #### |
| 2110 | # anon arrays with padrange |
| 2111 | my($a, $b); |
| 2112 | my $c = [$a, $b]; |
| 2113 | my $d = {$a, $b}; |
| 2114 | #### |
| 2115 | # slices with padrange |
| 2116 | my($a, $b); |
| 2117 | my(@x, %y); |
| 2118 | @x = @x[$a, $b]; |
| 2119 | @x = @y{$a, $b}; |
| 2120 | #### |
| 2121 | # binops with padrange |
| 2122 | my($a, $b, $c); |
| 2123 | $c = $a cmp $b; |
| 2124 | $c = $a + $b; |
| 2125 | $a += $b; |
| 2126 | $c = $a - $b; |
| 2127 | $a -= $b; |
| 2128 | $c = my $a1 cmp $b; |
| 2129 | $c = my $a2 + $b; |
| 2130 | $a += my $b1; |
| 2131 | $c = my $a3 - $b; |
| 2132 | $a -= my $b2; |
| 2133 | #### |
| 2134 | # 'x' with padrange |
| 2135 | my($a, $b, $c, $d, @e); |
| 2136 | $c = $a x $b; |
| 2137 | $a x= $b; |
| 2138 | @e = ($a) x $d; |
| 2139 | @e = ($a, $b) x $d; |
| 2140 | @e = ($a, $b, $c) x $d; |
| 2141 | @e = ($a, 1) x $d; |
| 2142 | #### |
| 2143 | # @_ with padrange |
| 2144 | my($a, $b, $c) = @_; |
| 2145 | #### |
| 2146 | # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version" |
| 2147 | # lexical subroutine |
| 2148 | # CONTEXT use feature 'lexical_subs'; |
| 2149 | no warnings "experimental::lexical_subs"; |
| 2150 | my sub f {} |
| 2151 | print f(); |
| 2152 | >>>> |
| 2153 | my sub f { |
| 2154 | |
| 2155 | } |
| 2156 | print f(); |
| 2157 | #### |
| 2158 | # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version" |
| 2159 | # lexical "state" subroutine |
| 2160 | # CONTEXT use feature 'state', 'lexical_subs'; |
| 2161 | no warnings 'experimental::lexical_subs'; |
| 2162 | state sub f {} |
| 2163 | print f(); |
| 2164 | >>>> |
| 2165 | state sub f { |
| 2166 | |
| 2167 | } |
| 2168 | print f(); |
| 2169 | #### |
| 2170 | # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version" |
| 2171 | # lexical subroutine scoping |
| 2172 | # CONTEXT use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; |
| 2173 | { |
| 2174 | { |
| 2175 | my sub a { die; } |
| 2176 | { |
| 2177 | foo(); |
| 2178 | my sub b; |
| 2179 | b; |
| 2180 | main::b(); |
| 2181 | &main::b; |
| 2182 | &main::b(); |
| 2183 | my $b = \&main::b; |
| 2184 | sub b { $b; } |
| 2185 | } |
| 2186 | } |
| 2187 | b(); |
| 2188 | } |
| 2189 | #### |
| 2190 | # self-referential lexical subroutine |
| 2191 | # CONTEXT use feature 'lexical_subs', 'state'; no warnings 'experimental::lexical_subs'; |
| 2192 | (); |
| 2193 | state sub sb2; |
| 2194 | sub sb2 { |
| 2195 | sb2; |
| 2196 | } |
| 2197 | #### |
| 2198 | # lexical subroutine with outer declaration and inner definition |
| 2199 | # CONTEXT use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; |
| 2200 | (); |
| 2201 | my sub f; |
| 2202 | my sub g { |
| 2203 | (); |
| 2204 | sub f { } |
| 2205 | } |
| 2206 | #### |
| 2207 | # lexical state subroutine with outer declaration and inner definition |
| 2208 | # CONTEXT use feature 'lexical_subs', 'state'; no warnings 'experimental::lexical_subs'; |
| 2209 | (); |
| 2210 | state sub sb4; |
| 2211 | state sub a { |
| 2212 | (); |
| 2213 | sub sb4 { } |
| 2214 | } |
| 2215 | state sub sb5; |
| 2216 | sub { |
| 2217 | (); |
| 2218 | sub sb5 { } |
| 2219 | } ; |
| 2220 | #### |
| 2221 | # Elements of %# should not be confused with $#{ array } |
| 2222 | () = ${#}{'foo'}; |
| 2223 | #### |
| 2224 | # $; [perl #123357] |
| 2225 | $_ = $;; |
| 2226 | do { |
| 2227 | $; |
| 2228 | }; |
| 2229 | #### |
| 2230 | # Ampersand calls and scalar context |
| 2231 | # OPTIONS -P |
| 2232 | package prototest; |
| 2233 | sub foo($$); |
| 2234 | foo(bar(),baz()); |
| 2235 | >>>> |
| 2236 | package prototest; |
| 2237 | &foo(scalar bar(), scalar baz()); |
| 2238 | #### |
| 2239 | # coderef2text and prototyped sub calls [perl #123435] |
| 2240 | is 'foo', 'oo'; |
| 2241 | #### |
| 2242 | # prototypes with unary precedence |
| 2243 | package prototest; |
| 2244 | sub dollar($) {} |
| 2245 | sub optdollar(;$) {} |
| 2246 | sub optoptdollar(;;$) {} |
| 2247 | sub splat(*) {} |
| 2248 | sub optsplat(;*) {} |
| 2249 | sub optoptsplat(;;*) {} |
| 2250 | sub bar(_) {} |
| 2251 | sub optbar(;_) {} |
| 2252 | sub optoptbar(;;_) {} |
| 2253 | sub plus(+) {} |
| 2254 | sub optplus(;+) {} |
| 2255 | sub optoptplus(;;+) {} |
| 2256 | sub wack(\$) {} |
| 2257 | sub optwack(;\$) {} |
| 2258 | sub optoptwack(;;\$) {} |
| 2259 | sub wackbrack(\[$]) {} |
| 2260 | sub optwackbrack(;\[$]) {} |
| 2261 | sub optoptwackbrack(;;\[$]) {} |
| 2262 | dollar($a < $b); |
| 2263 | optdollar($a < $b); |
| 2264 | optoptdollar($a < $b); |
| 2265 | splat($a < $b); # Some of these deparse with ‘&’; if that changes, just |
| 2266 | optsplat($a < $b); # change the tests. |
| 2267 | optoptsplat($a < $b); |
| 2268 | bar($a < $b); |
| 2269 | optbar($a < $b); |
| 2270 | optoptbar($a < $b); |
| 2271 | plus($a < $b); |
| 2272 | optplus($a < $b); |
| 2273 | optoptplus($a < $b); |
| 2274 | wack($a = $b); |
| 2275 | optwack($a = $b); |
| 2276 | optoptwack($a = $b); |
| 2277 | wackbrack($a = $b); |
| 2278 | optwackbrack($a = $b); |
| 2279 | optoptwackbrack($a = $b); |
| 2280 | optbar; |
| 2281 | optoptbar; |
| 2282 | optplus; |
| 2283 | optoptplus; |
| 2284 | optwack; |
| 2285 | optoptwack; |
| 2286 | optwackbrack; |
| 2287 | optoptwackbrack; |
| 2288 | >>>> |
| 2289 | package prototest; |
| 2290 | dollar($a < $b); |
| 2291 | optdollar($a < $b); |
| 2292 | optoptdollar($a < $b); |
| 2293 | &splat($a < $b); |
| 2294 | &optsplat($a < $b); |
| 2295 | &optoptsplat($a < $b); |
| 2296 | bar($a < $b); |
| 2297 | optbar($a < $b); |
| 2298 | optoptbar($a < $b); |
| 2299 | plus($a < $b); |
| 2300 | optplus($a < $b); |
| 2301 | optoptplus($a < $b); |
| 2302 | &wack(\($a = $b)); |
| 2303 | &optwack(\($a = $b)); |
| 2304 | &optoptwack(\($a = $b)); |
| 2305 | &wackbrack(\($a = $b)); |
| 2306 | &optwackbrack(\($a = $b)); |
| 2307 | &optoptwackbrack(\($a = $b)); |
| 2308 | optbar; |
| 2309 | optoptbar; |
| 2310 | optplus; |
| 2311 | optoptplus; |
| 2312 | optwack; |
| 2313 | optoptwack; |
| 2314 | optwackbrack; |
| 2315 | optoptwackbrack; |
| 2316 | #### |
| 2317 | # enreferencing prototypes: @ |
| 2318 | # CONTEXT sub wackat(\@) {} sub optwackat(;\@) {} sub wackbrackat(\[@]) {} sub optwackbrackat(;\[@]) {} |
| 2319 | wackat(my @a0); |
| 2320 | wackat(@a0); |
| 2321 | wackat(@ARGV); |
| 2322 | wackat(@{['t'];}); |
| 2323 | optwackat; |
| 2324 | optwackat(my @a1); |
| 2325 | optwackat(@a1); |
| 2326 | optwackat(@ARGV); |
| 2327 | optwackat(@{['t'];}); |
| 2328 | wackbrackat(my @a2); |
| 2329 | wackbrackat(@a2); |
| 2330 | wackbrackat(@ARGV); |
| 2331 | wackbrackat(@{['t'];}); |
| 2332 | optwackbrackat; |
| 2333 | optwackbrackat(my @a3); |
| 2334 | optwackbrackat(@a3); |
| 2335 | optwackbrackat(@ARGV); |
| 2336 | optwackbrackat(@{['t'];}); |
| 2337 | #### |
| 2338 | # enreferencing prototypes: % |
| 2339 | # CONTEXT sub wackperc(\%) {} sub optwackperc(;\%) {} sub wackbrackperc(\[%]) {} sub optwackbrackperc(;\[%]) {} |
| 2340 | wackperc(my %a0); |
| 2341 | wackperc(%a0); |
| 2342 | wackperc(%ARGV); |
| 2343 | wackperc(%{+{'t', 1};}); |
| 2344 | optwackperc; |
| 2345 | optwackperc(my %a1); |
| 2346 | optwackperc(%a1); |
| 2347 | optwackperc(%ARGV); |
| 2348 | optwackperc(%{+{'t', 1};}); |
| 2349 | wackbrackperc(my %a2); |
| 2350 | wackbrackperc(%a2); |
| 2351 | wackbrackperc(%ARGV); |
| 2352 | wackbrackperc(%{+{'t', 1};}); |
| 2353 | optwackbrackperc; |
| 2354 | optwackbrackperc(my %a3); |
| 2355 | optwackbrackperc(%a3); |
| 2356 | optwackbrackperc(%ARGV); |
| 2357 | optwackbrackperc(%{+{'t', 1};}); |
| 2358 | #### |
| 2359 | # enreferencing prototypes: + |
| 2360 | # CONTEXT sub plus(+) {} sub optplus(;+) {} |
| 2361 | plus('hi'); |
| 2362 | plus(my @a0); |
| 2363 | plus(my %h0); |
| 2364 | plus(\@a0); |
| 2365 | plus(\%h0); |
| 2366 | optplus; |
| 2367 | optplus('hi'); |
| 2368 | optplus(my @a1); |
| 2369 | optplus(my %h1); |
| 2370 | optplus(\@a1); |
| 2371 | optplus(\%h1); |
| 2372 | >>>> |
| 2373 | plus('hi'); |
| 2374 | plus(my @a0); |
| 2375 | plus(my %h0); |
| 2376 | plus(@a0); |
| 2377 | plus(%h0); |
| 2378 | optplus; |
| 2379 | optplus('hi'); |
| 2380 | optplus(my @a1); |
| 2381 | optplus(my %h1); |
| 2382 | optplus(@a1); |
| 2383 | optplus(%h1); |
| 2384 | #### |
| 2385 | # ensure aelemfast works in the range -128..127 and that there's no |
| 2386 | # funky edge cases |
| 2387 | my $x; |
| 2388 | no strict 'vars'; |
| 2389 | $x = $a[-256] + $a[-255] + $a[-129] + $a[-128] + $a[-127] + $a[-1] + $a[0]; |
| 2390 | $x = $a[1] + $a[126] + $a[127] + $a[128] + $a[255] + $a[256]; |
| 2391 | my @b; |
| 2392 | $x = $b[-256] + $b[-255] + $b[-129] + $b[-128] + $b[-127] + $b[-1] + $b[0]; |
| 2393 | $x = $b[1] + $b[126] + $b[127] + $b[128] + $b[255] + $b[256]; |
| 2394 | #### |
| 2395 | # 'm' must be preserved in m?? |
| 2396 | m??; |
| 2397 | #### |
| 2398 | # \(@array) and \(..., (@array), ...) |
| 2399 | my(@array, %hash, @a, @b, %c, %d); |
| 2400 | () = \(@array); |
| 2401 | () = \(%hash); |
| 2402 | () = \(@a, (@b), (%c), %d); |
| 2403 | () = \(@Foo::array); |
| 2404 | () = \(%Foo::hash); |
| 2405 | () = \(@Foo::a, (@Foo::b), (%Foo::c), %Foo::d); |
| 2406 | #### |
| 2407 | # subs synonymous with keywords |
| 2408 | main::our(); |
| 2409 | main::pop(); |
| 2410 | state(); |
| 2411 | use feature 'state'; |
| 2412 | main::state(); |
| 2413 | #### |
| 2414 | # lvalue references |
| 2415 | # CONTEXT use feature "state", 'refaliasing', 'lexical_subs'; no warnings 'experimental'; |
| 2416 | our $x; |
| 2417 | \$x = \$x; |
| 2418 | my $m; |
| 2419 | \$m = \$x; |
| 2420 | \my $n = \$x; |
| 2421 | (\$x) = @_; |
| 2422 | \($x) = @_; |
| 2423 | \($m) = @_; |
| 2424 | (\$m) = @_; |
| 2425 | \my($p) = @_; |
| 2426 | (\my $r) = @_; |
| 2427 | \($x, my $a) = @{[\$x, \$x]}; |
| 2428 | (\$x, \my $b) = @{[\$x, \$x]}; |
| 2429 | \local $x = \3; |
| 2430 | \local($x) = \3; |
| 2431 | \state $c = \3; |
| 2432 | \state($d) = \3; |
| 2433 | \our $e = \3; |
| 2434 | \our($f) = \3; |
| 2435 | \$_[0] = foo(); |
| 2436 | \($_[1]) = foo(); |
| 2437 | my @a; |
| 2438 | \$a[0] = foo(); |
| 2439 | \($a[1]) = foo(); |
| 2440 | \local($a[1]) = foo(); |
| 2441 | \@a[0,1] = foo(); |
| 2442 | \(@a[2,3]) = foo(); |
| 2443 | \local @a[0,1] = (\$a)x2; |
| 2444 | \$_{a} = foo(); |
| 2445 | \($_{b}) = foo(); |
| 2446 | my %h; |
| 2447 | \$h{a} = foo(); |
| 2448 | \($h{b}) = foo(); |
| 2449 | \local $h{a} = \$x; |
| 2450 | \local($h{b}) = \$x; |
| 2451 | \@h{'a','b'} = foo(); |
| 2452 | \(@h{2,3}) = foo(); |
| 2453 | \local @h{'a','b'} = (\$x)x2; |
| 2454 | \@_ = foo(); |
| 2455 | \@a = foo(); |
| 2456 | (\@_) = foo(); |
| 2457 | (\@a) = foo(); |
| 2458 | \my @c = foo(); |
| 2459 | (\my @d) = foo(); |
| 2460 | \(@_) = foo(); |
| 2461 | \(@a) = foo(); |
| 2462 | \my(@g) = foo(); |
| 2463 | \local @_ = \@_; |
| 2464 | (\local @_) = \@_; |
| 2465 | \state @e = [1..3]; |
| 2466 | \state(@f) = \3; |
| 2467 | \our @i = [1..3]; |
| 2468 | \our(@h) = \3; |
| 2469 | \%_ = foo(); |
| 2470 | \%h = foo(); |
| 2471 | (\%_) = foo(); |
| 2472 | (\%h) = foo(); |
| 2473 | \my %c = foo(); |
| 2474 | (\my %d) = foo(); |
| 2475 | \local %_ = \%h; |
| 2476 | (\local %_) = \%h; |
| 2477 | \state %y = {1,2}; |
| 2478 | \our %z = {1,2}; |
| 2479 | (\our %zz) = {1,2}; |
| 2480 | \&a = foo(); |
| 2481 | (\&a) = foo(); |
| 2482 | \(&a) = foo(); |
| 2483 | { |
| 2484 | my sub a; |
| 2485 | \&a = foo(); |
| 2486 | (\&a) = foo(); |
| 2487 | \(&a) = foo(); |
| 2488 | } |
| 2489 | (\$_, $_) = \(1, 2); |
| 2490 | $_ == 3 ? \$_ : $_ = \3; |
| 2491 | $_ == 3 ? \$_ : \$x = \3; |
| 2492 | \($_ == 3 ? $_ : $x) = \3; |
| 2493 | for \my $topic (\$1, \$2) { |
| 2494 | die; |
| 2495 | } |
| 2496 | for \state $topic (\$1, \$2) { |
| 2497 | die; |
| 2498 | } |
| 2499 | for \our $topic (\$1, \$2) { |
| 2500 | die; |
| 2501 | } |
| 2502 | for \$_ (\$1, \$2) { |
| 2503 | die; |
| 2504 | } |
| 2505 | for \my @a ([1,2], [3,4]) { |
| 2506 | die; |
| 2507 | } |
| 2508 | for \state @a ([1,2], [3,4]) { |
| 2509 | die; |
| 2510 | } |
| 2511 | for \our @a ([1,2], [3,4]) { |
| 2512 | die; |
| 2513 | } |
| 2514 | for \@_ ([1,2], [3,4]) { |
| 2515 | die; |
| 2516 | } |
| 2517 | for \my %a ({5,6}, {7,8}) { |
| 2518 | die; |
| 2519 | } |
| 2520 | for \our %a ({5,6}, {7,8}) { |
| 2521 | die; |
| 2522 | } |
| 2523 | for \state %a ({5,6}, {7,8}) { |
| 2524 | die; |
| 2525 | } |
| 2526 | for \%_ ({5,6}, {7,8}) { |
| 2527 | die; |
| 2528 | } |
| 2529 | { |
| 2530 | my sub a; |
| 2531 | for \&a (sub { 9; }, sub { 10; }) { |
| 2532 | die; |
| 2533 | } |
| 2534 | } |
| 2535 | for \&a (sub { 9; }, sub { 10; }) { |
| 2536 | die; |
| 2537 | } |
| 2538 | >>>> |
| 2539 | our $x; |
| 2540 | \$x = \$x; |
| 2541 | my $m; |
| 2542 | \$m = \$x; |
| 2543 | \my $n = \$x; |
| 2544 | (\$x) = @_; |
| 2545 | (\$x) = @_; |
| 2546 | (\$m) = @_; |
| 2547 | (\$m) = @_; |
| 2548 | (\my $p) = @_; |
| 2549 | (\my $r) = @_; |
| 2550 | (\$x, \my $a) = @{[\$x, \$x];}; |
| 2551 | (\$x, \my $b) = @{[\$x, \$x];}; |
| 2552 | \local $x = \3; |
| 2553 | (\local $x) = \3; |
| 2554 | \state $c = \3; |
| 2555 | (\state $d) = \3; |
| 2556 | \our $e = \3; |
| 2557 | (\our $f) = \3; |
| 2558 | \$_[0] = foo(); |
| 2559 | (\$_[1]) = foo(); |
| 2560 | my @a; |
| 2561 | \$a[0] = foo(); |
| 2562 | (\$a[1]) = foo(); |
| 2563 | (\local $a[1]) = foo(); |
| 2564 | (\@a[0, 1]) = foo(); |
| 2565 | (\@a[2, 3]) = foo(); |
| 2566 | (\local @a[0, 1]) = (\$a) x 2; |
| 2567 | \$_{'a'} = foo(); |
| 2568 | (\$_{'b'}) = foo(); |
| 2569 | my %h; |
| 2570 | \$h{'a'} = foo(); |
| 2571 | (\$h{'b'}) = foo(); |
| 2572 | \local $h{'a'} = \$x; |
| 2573 | (\local $h{'b'}) = \$x; |
| 2574 | (\@h{'a', 'b'}) = foo(); |
| 2575 | (\@h{2, 3}) = foo(); |
| 2576 | (\local @h{'a', 'b'}) = (\$x) x 2; |
| 2577 | \@_ = foo(); |
| 2578 | \@a = foo(); |
| 2579 | (\@_) = foo(); |
| 2580 | (\@a) = foo(); |
| 2581 | \my @c = foo(); |
| 2582 | (\my @d) = foo(); |
| 2583 | (\(@_)) = foo(); |
| 2584 | (\(@a)) = foo(); |
| 2585 | (\(my @g)) = foo(); |
| 2586 | \local @_ = \@_; |
| 2587 | (\local @_) = \@_; |
| 2588 | \state @e = [1..3]; |
| 2589 | (\(state @f)) = \3; |
| 2590 | \our @i = [1..3]; |
| 2591 | (\(our @h)) = \3; |
| 2592 | \%_ = foo(); |
| 2593 | \%h = foo(); |
| 2594 | (\%_) = foo(); |
| 2595 | (\%h) = foo(); |
| 2596 | \my %c = foo(); |
| 2597 | (\my %d) = foo(); |
| 2598 | \local %_ = \%h; |
| 2599 | (\local %_) = \%h; |
| 2600 | \state %y = {1, 2}; |
| 2601 | \our %z = {1, 2}; |
| 2602 | (\our %zz) = {1, 2}; |
| 2603 | \&a = foo(); |
| 2604 | (\&a) = foo(); |
| 2605 | (\&a) = foo(); |
| 2606 | { |
| 2607 | my sub a; |
| 2608 | \&a = foo(); |
| 2609 | (\&a) = foo(); |
| 2610 | (\&a) = foo(); |
| 2611 | } |
| 2612 | (\$_, $_) = \(1, 2); |
| 2613 | $_ == 3 ? \$_ : $_ = \3; |
| 2614 | $_ == 3 ? \$_ : \$x = \3; |
| 2615 | ($_ == 3 ? \$_ : \$x) = \3; |
| 2616 | foreach \my $topic (\$1, \$2) { |
| 2617 | die; |
| 2618 | } |
| 2619 | foreach \state $topic (\$1, \$2) { |
| 2620 | die; |
| 2621 | } |
| 2622 | foreach \our $topic (\$1, \$2) { |
| 2623 | die; |
| 2624 | } |
| 2625 | foreach \$_ (\$1, \$2) { |
| 2626 | die; |
| 2627 | } |
| 2628 | foreach \my @a ([1, 2], [3, 4]) { |
| 2629 | die; |
| 2630 | } |
| 2631 | foreach \state @a ([1, 2], [3, 4]) { |
| 2632 | die; |
| 2633 | } |
| 2634 | foreach \our @a ([1, 2], [3, 4]) { |
| 2635 | die; |
| 2636 | } |
| 2637 | foreach \@_ ([1, 2], [3, 4]) { |
| 2638 | die; |
| 2639 | } |
| 2640 | foreach \my %a ({5, 6}, {7, 8}) { |
| 2641 | die; |
| 2642 | } |
| 2643 | foreach \our %a ({5, 6}, {7, 8}) { |
| 2644 | die; |
| 2645 | } |
| 2646 | foreach \state %a ({5, 6}, {7, 8}) { |
| 2647 | die; |
| 2648 | } |
| 2649 | foreach \%_ ({5, 6}, {7, 8}) { |
| 2650 | die; |
| 2651 | } |
| 2652 | { |
| 2653 | my sub a; |
| 2654 | foreach \&a (sub { 9; } , sub { 10; } ) { |
| 2655 | die; |
| 2656 | } |
| 2657 | } |
| 2658 | foreach \&a (sub { 9; } , sub { 10; } ) { |
| 2659 | die; |
| 2660 | } |
| 2661 | #### |
| 2662 | # CONTEXT no warnings 'experimental::for_list'; |
| 2663 | my %hash; |
| 2664 | foreach my ($key, $value) (%hash) { |
| 2665 | study $_; |
| 2666 | } |
| 2667 | #### |
| 2668 | # CONTEXT no warnings 'experimental::for_list'; |
| 2669 | my @ducks; |
| 2670 | foreach my ($tick, $trick, $track) (@ducks) { |
| 2671 | study $_; |
| 2672 | } |
| 2673 | #### |
| 2674 | # join $foo, pos |
| 2675 | my $foo; |
| 2676 | $_ = join $foo, pos |
| 2677 | >>>> |
| 2678 | my $foo; |
| 2679 | $_ = join('???', pos $_); |
| 2680 | #### |
| 2681 | # exists $a[0] |
| 2682 | our @a; |
| 2683 | exists $a[0]; |
| 2684 | #### |
| 2685 | # my @a; exists $a[0] |
| 2686 | my @a; |
| 2687 | exists $a[0]; |
| 2688 | #### |
| 2689 | # delete $a[0] |
| 2690 | our @a; |
| 2691 | delete $a[0]; |
| 2692 | #### |
| 2693 | # my @a; delete $a[0] |
| 2694 | my @a; |
| 2695 | delete $a[0]; |
| 2696 | #### |
| 2697 | # $_[0][$_[1]] |
| 2698 | $_[0][$_[1]]; |
| 2699 | #### |
| 2700 | # f($a[0]); |
| 2701 | my @a; |
| 2702 | f($a[0]); |
| 2703 | #### |
| 2704 | #qr/\Q$h{'key'}\E/; |
| 2705 | my %h; |
| 2706 | qr/\Q$h{'key'}\E/; |
| 2707 | #### |
| 2708 | # my $x = "$h{foo}"; |
| 2709 | my %h; |
| 2710 | my $x = "$h{'foo'}"; |
| 2711 | #### |
| 2712 | # weird constant hash key |
| 2713 | my %h; |
| 2714 | my $x = $h{"\000\t\x{100}"}; |
| 2715 | #### |
| 2716 | # multideref and packages |
| 2717 | package foo; |
| 2718 | my(%bar) = ('a', 'b'); |
| 2719 | our(@bar) = (1, 2); |
| 2720 | $bar{'k'} = $bar[200]; |
| 2721 | $main::bar{'k'} = $main::bar[200]; |
| 2722 | $foo::bar{'k'} = $foo::bar[200]; |
| 2723 | package foo2; |
| 2724 | $bar{'k'} = $bar[200]; |
| 2725 | $main::bar{'k'} = $main::bar[200]; |
| 2726 | $foo::bar{'k'} = $foo::bar[200]; |
| 2727 | >>>> |
| 2728 | package foo; |
| 2729 | my(%bar) = ('a', 'b'); |
| 2730 | our(@bar) = (1, 2); |
| 2731 | $bar{'k'} = $bar[200]; |
| 2732 | $main::bar{'k'} = $main::bar[200]; |
| 2733 | $foo::bar{'k'} = $bar[200]; |
| 2734 | package foo2; |
| 2735 | $bar{'k'} = $foo::bar[200]; |
| 2736 | $main::bar{'k'} = $main::bar[200]; |
| 2737 | $foo::bar{'k'} = $foo::bar[200]; |
| 2738 | #### |
| 2739 | # multideref and local |
| 2740 | my %h; |
| 2741 | local $h{'foo'}[0] = 1; |
| 2742 | #### |
| 2743 | # multideref and exists |
| 2744 | my(%h, $i); |
| 2745 | my $e = exists $h{'foo'}[$i]; |
| 2746 | #### |
| 2747 | # multideref and delete |
| 2748 | my(%h, $i); |
| 2749 | my $e = delete $h{'foo'}[$i]; |
| 2750 | #### |
| 2751 | # multideref with leading expression |
| 2752 | my $r; |
| 2753 | my $x = +($r // [])->{'foo'}[0]; |
| 2754 | #### |
| 2755 | # multideref with complex middle index |
| 2756 | my(%h, $i, $j, $k); |
| 2757 | my $x = $h{'foo'}[$i + $j]{$k}; |
| 2758 | #### |
| 2759 | # multideref with trailing non-simple index that initially looks simple |
| 2760 | # (i.e. the constant "3") |
| 2761 | my($r, $i, $j, $k); |
| 2762 | my $x = +($r || {})->{'foo'}[$i + $j]{3 + $k}; |
| 2763 | #### |
| 2764 | # chdir |
| 2765 | chdir 'file'; |
| 2766 | chdir FH; |
| 2767 | chdir; |
| 2768 | #### |
| 2769 | # 5.22 bitops |
| 2770 | # CONTEXT use feature "bitwise"; no warnings "experimental::bitwise"; |
| 2771 | $_ = $_ | $_; |
| 2772 | $_ = $_ & $_; |
| 2773 | $_ = $_ ^ $_; |
| 2774 | $_ = ~$_; |
| 2775 | $_ = $_ |. $_; |
| 2776 | $_ = $_ &. $_; |
| 2777 | $_ = $_ ^. $_; |
| 2778 | $_ = ~.$_; |
| 2779 | $_ |= $_; |
| 2780 | $_ &= $_; |
| 2781 | $_ ^= $_; |
| 2782 | $_ |.= $_; |
| 2783 | $_ &.= $_; |
| 2784 | $_ ^.= $_; |
| 2785 | #### |
| 2786 | #### |
| 2787 | # Should really use 'no warnings "experimental::signatures"', |
| 2788 | # but it doesn't yet deparse correctly. |
| 2789 | # anon subs used because this test framework doesn't deparse named subs |
| 2790 | # in the DATA code snippets. |
| 2791 | # |
| 2792 | # general signature |
| 2793 | no warnings; |
| 2794 | use feature 'signatures'; |
| 2795 | my $x; |
| 2796 | sub ($a, $, $b = $glo::bal, $c = $a, $d = 'foo', $e = -37, $f = 0, $g = 1, $h = undef, $i = $a + 1, $j = /foo/, @) { |
| 2797 | $x++; |
| 2798 | } |
| 2799 | ; |
| 2800 | $x++; |
| 2801 | #### |
| 2802 | # Signature and prototype |
| 2803 | no warnings; |
| 2804 | use feature 'signatures'; |
| 2805 | my $x; |
| 2806 | my $f = sub : prototype($$) ($a, $b) { |
| 2807 | $x++; |
| 2808 | } |
| 2809 | ; |
| 2810 | $x++; |
| 2811 | #### |
| 2812 | # Signature and prototype and attrs |
| 2813 | no warnings; |
| 2814 | use feature 'signatures'; |
| 2815 | my $x; |
| 2816 | my $f = sub : prototype($$) lvalue ($a, $b) { |
| 2817 | $x++; |
| 2818 | } |
| 2819 | ; |
| 2820 | $x++; |
| 2821 | #### |
| 2822 | # Signature and attrs |
| 2823 | no warnings; |
| 2824 | use feature 'signatures'; |
| 2825 | my $x; |
| 2826 | my $f = sub : lvalue method ($a, $b) { |
| 2827 | $x++; |
| 2828 | } |
| 2829 | ; |
| 2830 | $x++; |
| 2831 | #### |
| 2832 | # named array slurp, null body |
| 2833 | no warnings; |
| 2834 | use feature 'signatures'; |
| 2835 | sub (@a) { |
| 2836 | ; |
| 2837 | } |
| 2838 | ; |
| 2839 | #### |
| 2840 | # named hash slurp |
| 2841 | no warnings; |
| 2842 | use feature 'signatures'; |
| 2843 | sub ($key, %h) { |
| 2844 | $h{$key}; |
| 2845 | } |
| 2846 | ; |
| 2847 | #### |
| 2848 | # anon hash slurp |
| 2849 | no warnings; |
| 2850 | use feature 'signatures'; |
| 2851 | sub ($a, %) { |
| 2852 | $a; |
| 2853 | } |
| 2854 | ; |
| 2855 | #### |
| 2856 | # parenthesised default arg |
| 2857 | no warnings; |
| 2858 | use feature 'signatures'; |
| 2859 | sub ($a, $b = (/foo/), $c = 1) { |
| 2860 | $a + $b + $c; |
| 2861 | } |
| 2862 | ; |
| 2863 | #### |
| 2864 | # parenthesised default arg with TARGMY |
| 2865 | no warnings; |
| 2866 | use feature 'signatures'; |
| 2867 | sub ($a, $b = ($a + 1), $c = 1) { |
| 2868 | $a + $b + $c; |
| 2869 | } |
| 2870 | ; |
| 2871 | #### |
| 2872 | # empty default |
| 2873 | no warnings; |
| 2874 | use feature 'signatures'; |
| 2875 | sub ($a, $=) { |
| 2876 | $a; |
| 2877 | } |
| 2878 | ; |
| 2879 | #### |
| 2880 | # defined-or default |
| 2881 | no warnings; |
| 2882 | use feature 'signatures'; |
| 2883 | sub ($a //= 'default') { |
| 2884 | $a; |
| 2885 | } |
| 2886 | ; |
| 2887 | #### |
| 2888 | # logical-or default |
| 2889 | no warnings; |
| 2890 | use feature 'signatures'; |
| 2891 | sub ($a ||= 'default') { |
| 2892 | $a; |
| 2893 | } |
| 2894 | ; |
| 2895 | #### |
| 2896 | # padrange op within pattern code blocks |
| 2897 | /(?{ my($x, $y) = (); })/; |
| 2898 | my $a; |
| 2899 | /$a(?{ my($x, $y) = (); })/; |
| 2900 | my $r1 = qr/(?{ my($x, $y) = (); })/; |
| 2901 | my $r2 = qr/$a(?{ my($x, $y) = (); })/; |
| 2902 | #### |
| 2903 | # don't remove pattern whitespace escapes |
| 2904 | /a\ b/; |
| 2905 | /a\ b/x; |
| 2906 | /a\ b/; |
| 2907 | /a\ b/x; |
| 2908 | #### |
| 2909 | # my attributes |
| 2910 | my $s1 :foo(f1, f2) bar(b1, b2); |
| 2911 | my @a1 :foo(f1, f2) bar(b1, b2); |
| 2912 | my %h1 :foo(f1, f2) bar(b1, b2); |
| 2913 | my($s2, @a2, %h2) :foo(f1, f2) bar(b1, b2); |
| 2914 | #### |
| 2915 | # my class attributes |
| 2916 | package Foo::Bar; |
| 2917 | my Foo::Bar $s1 :foo(f1, f2) bar(b1, b2); |
| 2918 | my Foo::Bar @a1 :foo(f1, f2) bar(b1, b2); |
| 2919 | my Foo::Bar %h1 :foo(f1, f2) bar(b1, b2); |
| 2920 | my Foo::Bar ($s2, @a2, %h2) :foo(f1, f2) bar(b1, b2); |
| 2921 | package main; |
| 2922 | my Foo::Bar $s3 :foo(f1, f2) bar(b1, b2); |
| 2923 | my Foo::Bar @a3 :foo(f1, f2) bar(b1, b2); |
| 2924 | my Foo::Bar %h3 :foo(f1, f2) bar(b1, b2); |
| 2925 | my Foo::Bar ($s4, @a4, %h4) :foo(f1, f2) bar(b1, b2); |
| 2926 | #### |
| 2927 | # avoid false positives in my $x :attribute |
| 2928 | 'attributes'->import('main', \my $x1, 'foo(bar)'), my $y1; |
| 2929 | 'attributes'->import('Fooo', \my $x2, 'foo(bar)'), my $y2; |
| 2930 | #### |
| 2931 | # hash slices and hash key/value slices |
| 2932 | my(@a, %h); |
| 2933 | our(@oa, %oh); |
| 2934 | @a = @h{'foo', 'bar'}; |
| 2935 | @a = %h{'foo', 'bar'}; |
| 2936 | @a = delete @h{'foo', 'bar'}; |
| 2937 | @a = delete %h{'foo', 'bar'}; |
| 2938 | @oa = @oh{'foo', 'bar'}; |
| 2939 | @oa = %oh{'foo', 'bar'}; |
| 2940 | @oa = delete @oh{'foo', 'bar'}; |
| 2941 | @oa = delete %oh{'foo', 'bar'}; |
| 2942 | #### |
| 2943 | # keys optimised away in void and scalar context |
| 2944 | no warnings; |
| 2945 | ; |
| 2946 | our %h1; |
| 2947 | my($x, %h2); |
| 2948 | %h1; |
| 2949 | keys %h1; |
| 2950 | $x = %h1; |
| 2951 | $x = keys %h1; |
| 2952 | %h2; |
| 2953 | keys %h2; |
| 2954 | $x = %h2; |
| 2955 | $x = keys %h2; |
| 2956 | #### |
| 2957 | # eq,const optimised away for (index() == -1) |
| 2958 | my($a, $b); |
| 2959 | our $c; |
| 2960 | $c = index($a, $b) == 2; |
| 2961 | $c = rindex($a, $b) == 2; |
| 2962 | $c = index($a, $b) == -1; |
| 2963 | $c = rindex($a, $b) == -1; |
| 2964 | $c = index($a, $b) != -1; |
| 2965 | $c = rindex($a, $b) != -1; |
| 2966 | $c = (index($a, $b) == -1); |
| 2967 | $c = (rindex($a, $b) == -1); |
| 2968 | $c = (index($a, $b) != -1); |
| 2969 | $c = (rindex($a, $b) != -1); |
| 2970 | #### |
| 2971 | # eq,const,sassign,madmy optimised away for (index() == -1) |
| 2972 | my($a, $b); |
| 2973 | my $c; |
| 2974 | $c = index($a, $b) == 2; |
| 2975 | $c = rindex($a, $b) == 2; |
| 2976 | $c = index($a, $b) == -1; |
| 2977 | $c = rindex($a, $b) == -1; |
| 2978 | $c = index($a, $b) != -1; |
| 2979 | $c = rindex($a, $b) != -1; |
| 2980 | $c = (index($a, $b) == -1); |
| 2981 | $c = (rindex($a, $b) == -1); |
| 2982 | $c = (index($a, $b) != -1); |
| 2983 | $c = (rindex($a, $b) != -1); |
| 2984 | #### |
| 2985 | # plain multiconcat |
| 2986 | my($a, $b, $c, $d, @a); |
| 2987 | $d = length $a . $b . $c; |
| 2988 | $d = length($a) . $b . $c; |
| 2989 | print '' . $a; |
| 2990 | push @a, ($a . '') * $b; |
| 2991 | unshift @a, "$a" * ($b . ''); |
| 2992 | print $a . 'x' . $b . $c; |
| 2993 | print $a . 'x' . $b . $c, $d; |
| 2994 | print $b . $c . ($a . $b); |
| 2995 | print $b . $c . ($a . $b); |
| 2996 | print $b . $c . @a; |
| 2997 | print $a . "\x{100}"; |
| 2998 | #### |
| 2999 | # double-quoted multiconcat |
| 3000 | my($a, $b, $c, $d, @a); |
| 3001 | print "${a}x\x{100}$b$c"; |
| 3002 | print "$a\Q$b\E$c\Ua$a\E\Lb$b\uc$c\E$a${b}c$c"; |
| 3003 | print "A=$a[length 'b' . $c . 'd'] b=$b"; |
| 3004 | print "A=@a B=$b"; |
| 3005 | print "\x{101}$a\x{100}"; |
| 3006 | $a = qr/\Q |
| 3007 | $b $c |
| 3008 | \x80 |
| 3009 | \x{100} |
| 3010 | \E$c |
| 3011 | /; |
| 3012 | #### |
| 3013 | # sprintf multiconcat |
| 3014 | my($a, $b, $c, $d, @a); |
| 3015 | print sprintf("%s%s%%%sx%s\x{100}%s", $a, $b, $c, scalar @a, $d); |
| 3016 | #### |
| 3017 | # multiconcat with lexical assign |
| 3018 | my($a, $b, $c, $d, $e, @a); |
| 3019 | $d = 'foo' . $a; |
| 3020 | $d = "foo$a"; |
| 3021 | $d = $a . ''; |
| 3022 | $d = 'foo' . $a . 'bar'; |
| 3023 | $d = $a . $b; |
| 3024 | $d = $a . $b . $c; |
| 3025 | $d = $a . $b . $c . @a; |
| 3026 | $e = ($d = $a . $b . $c); |
| 3027 | $d = !$a . $b . $c; |
| 3028 | $a = $b . $c . ($a . $b); |
| 3029 | $e = f($d = !$a . $b) . $c; |
| 3030 | $d = "${a}x\x{100}$b$c"; |
| 3031 | f($d = !$a . $b . $c); |
| 3032 | #### |
| 3033 | # multiconcat with lexical my |
| 3034 | my($a, $b, $c, $d, $e, @a); |
| 3035 | my $d1 = 'foo' . $a; |
| 3036 | my $d2 = "foo$a"; |
| 3037 | my $d3 = $a . ''; |
| 3038 | my $d4 = 'foo' . $a . 'bar'; |
| 3039 | my $d5 = $a . $b; |
| 3040 | my $d6 = $a . $b . $c; |
| 3041 | my $e7 = ($d = $a . $b . $c); |
| 3042 | my $d8 = !$a . $b . $c; |
| 3043 | my $d9 = $b . $c . ($a . $b); |
| 3044 | my $da = f($d = !$a . $b) . $c; |
| 3045 | my $dc = "${a}x\x{100}$b$c"; |
| 3046 | f(my $db = !$a . $b . $c); |
| 3047 | my $dd = $a . $b . $c . @a; |
| 3048 | #### |
| 3049 | # multiconcat with lexical append |
| 3050 | my($a, $b, $c, $d, $e, @a); |
| 3051 | $d .= ''; |
| 3052 | $d .= $a; |
| 3053 | $d .= "$a"; |
| 3054 | $d .= 'foo' . $a; |
| 3055 | $d .= "foo$a"; |
| 3056 | $d .= $a . ''; |
| 3057 | $d .= 'foo' . $a . 'bar'; |
| 3058 | $d .= $a . $b; |
| 3059 | $d .= $a . $b . $c; |
| 3060 | $d .= $a . $b . @a; |
| 3061 | $e .= ($d = $a . $b . $c); |
| 3062 | $d .= !$a . $b . $c; |
| 3063 | $a .= $b . $c . ($a . $b); |
| 3064 | $e .= f($d .= !$a . $b) . $c; |
| 3065 | f($d .= !$a . $b . $c); |
| 3066 | $d .= "${a}x\x{100}$b$c"; |
| 3067 | #### |
| 3068 | # multiconcat with expression assign |
| 3069 | my($a, $b, $c, @a); |
| 3070 | our($d, $e); |
| 3071 | $d = 'foo' . $a; |
| 3072 | $d = "foo$a"; |
| 3073 | $d = $a . ''; |
| 3074 | $d = 'foo' . $a . 'bar'; |
| 3075 | $d = $a . $b; |
| 3076 | $d = $a . $b . $c; |
| 3077 | $d = $a . $b . @a; |
| 3078 | $e = ($d = $a . $b . $c); |
| 3079 | $a["-$b-"] = !$a . $b . $c; |
| 3080 | $a[$b]{$c}{$d ? $a : $b . $c} = !$a . $b . $c; |
| 3081 | $a = $b . $c . ($a . $b); |
| 3082 | $e = f($d = !$a . $b) . $c; |
| 3083 | $d = "${a}x\x{100}$b$c"; |
| 3084 | f($d = !$a . $b . $c); |
| 3085 | #### |
| 3086 | # multiconcat with expression concat |
| 3087 | my($a, $b, $c, @a); |
| 3088 | our($d, $e); |
| 3089 | $d .= 'foo' . $a; |
| 3090 | $d .= "foo$a"; |
| 3091 | $d .= $a . ''; |
| 3092 | $d .= 'foo' . $a . 'bar'; |
| 3093 | $d .= $a . $b; |
| 3094 | $d .= $a . $b . $c; |
| 3095 | $d .= $a . $b . @a; |
| 3096 | $e .= ($d .= $a . $b . $c); |
| 3097 | $a["-$b-"] .= !$a . $b . $c; |
| 3098 | $a[$b]{$c}{$d ? $a : $b . $c} .= !$a . $b . $c; |
| 3099 | $a .= $b . $c . ($a . $b); |
| 3100 | $e .= f($d .= !$a . $b) . $c; |
| 3101 | $d .= "${a}x\x{100}$b$c"; |
| 3102 | f($d .= !$a . $b . $c); |
| 3103 | #### |
| 3104 | # multiconcat with CORE::sprintf |
| 3105 | # CONTEXT sub sprintf {} |
| 3106 | my($a, $b); |
| 3107 | my $x = CORE::sprintf('%s%s', $a, $b); |
| 3108 | #### |
| 3109 | # multiconcat with backticks |
| 3110 | my($a, $b); |
| 3111 | our $x; |
| 3112 | $x = `$a-$b`; |
| 3113 | #### |
| 3114 | # multiconcat within qr// |
| 3115 | my($r, $a, $b); |
| 3116 | $r = qr/abc\Q$a-$b\Exyz/; |
| 3117 | #### |
| 3118 | # tr with unprintable characters |
| 3119 | my $str; |
| 3120 | $str = 'foo'; |
| 3121 | $str =~ tr/\cA//; |
| 3122 | #### |
| 3123 | # CORE::foo special case in bareword parsing |
| 3124 | print $CORE::foo, $CORE::foo::bar; |
| 3125 | print @CORE::foo, @CORE::foo::bar; |
| 3126 | print %CORE::foo, %CORE::foo::bar; |
| 3127 | print $CORE::foo{'a'}, $CORE::foo::bar{'a'}; |
| 3128 | print &CORE::foo, &CORE::foo::bar; |
| 3129 | print &CORE::foo(), &CORE::foo::bar(); |
| 3130 | print \&CORE::foo, \&CORE::foo::bar; |
| 3131 | print *CORE::foo, *CORE::foo::bar; |
| 3132 | print stat CORE::foo::, stat CORE::foo::bar; |
| 3133 | print CORE::foo:: 1; |
| 3134 | print CORE::foo::bar 2; |
| 3135 | #### |
| 3136 | # trailing colons on glob names |
| 3137 | no strict 'vars'; |
| 3138 | $Foo::::baz = 1; |
| 3139 | print $foo, $foo::, $foo::::; |
| 3140 | print @foo, @foo::, @foo::::; |
| 3141 | print %foo, %foo::, %foo::::; |
| 3142 | print $foo{'a'}, $foo::{'a'}, $foo::::{'a'}; |
| 3143 | print &foo, &foo::, &foo::::; |
| 3144 | print &foo(), &foo::(), &foo::::(); |
| 3145 | print \&foo, \&foo::, \&foo::::; |
| 3146 | print *foo, *foo::, *foo::::; |
| 3147 | print stat Foo, stat Foo::::; |
| 3148 | print Foo 1; |
| 3149 | print Foo:::: 2; |
| 3150 | #### |
| 3151 | # trailing colons mixed with CORE |
| 3152 | no strict 'vars'; |
| 3153 | print $CORE, $CORE::, $CORE::::; |
| 3154 | print @CORE, @CORE::, @CORE::::; |
| 3155 | print %CORE, %CORE::, %CORE::::; |
| 3156 | print $CORE{'a'}, $CORE::{'a'}, $CORE::::{'a'}; |
| 3157 | print &CORE, &CORE::, &CORE::::; |
| 3158 | print &CORE(), &CORE::(), &CORE::::(); |
| 3159 | print \&CORE, \&CORE::, \&CORE::::; |
| 3160 | print *CORE, *CORE::, *CORE::::; |
| 3161 | print stat CORE, stat CORE::::; |
| 3162 | print CORE 1; |
| 3163 | print CORE:::: 2; |
| 3164 | print $CORE::foo, $CORE::foo::, $CORE::foo::::; |
| 3165 | print @CORE::foo, @CORE::foo::, @CORE::foo::::; |
| 3166 | print %CORE::foo, %CORE::foo::, %CORE::foo::::; |
| 3167 | print $CORE::foo{'a'}, $CORE::foo::{'a'}, $CORE::foo::::{'a'}; |
| 3168 | print &CORE::foo, &CORE::foo::, &CORE::foo::::; |
| 3169 | print &CORE::foo(), &CORE::foo::(), &CORE::foo::::(); |
| 3170 | print \&CORE::foo, \&CORE::foo::, \&CORE::foo::::; |
| 3171 | print *CORE::foo, *CORE::foo::, *CORE::foo::::; |
| 3172 | print stat CORE::foo::, stat CORE::foo::::; |
| 3173 | print CORE::foo:: 1; |
| 3174 | print CORE::foo:::: 2; |
| 3175 | #### |
| 3176 | # \&foo |
| 3177 | my sub foo { |
| 3178 | 1; |
| 3179 | } |
| 3180 | no strict 'vars'; |
| 3181 | print \&main::foo; |
| 3182 | print \&{foo}; |
| 3183 | print \&bar; |
| 3184 | use strict 'vars'; |
| 3185 | print \&main::foo; |
| 3186 | print \&{foo}; |
| 3187 | print \&main::bar; |
| 3188 | #### |
| 3189 | # exists(&foo) |
| 3190 | my sub foo { |
| 3191 | 1; |
| 3192 | } |
| 3193 | no strict 'vars'; |
| 3194 | print exists &main::foo; |
| 3195 | print exists &{foo}; |
| 3196 | print exists &bar; |
| 3197 | use strict 'vars'; |
| 3198 | print exists &main::foo; |
| 3199 | print exists &{foo}; |
| 3200 | print exists &main::bar; |
| 3201 | # precedence of optimised-away 'keys' (OPpPADHV_ISKEYS/OPpRV2HV_ISKEYS) |
| 3202 | my($r1, %h1, $res); |
| 3203 | our($r2, %h2); |
| 3204 | $res = keys %h1; |
| 3205 | $res = keys %h2; |
| 3206 | $res = keys %$r1; |
| 3207 | $res = keys %$r2; |
| 3208 | $res = keys(%h1) / 2 - 1; |
| 3209 | $res = keys(%h2) / 2 - 1; |
| 3210 | $res = keys(%$r1) / 2 - 1; |
| 3211 | $res = keys(%$r2) / 2 - 1; |
| 3212 | #### |
| 3213 | # ditto in presence of sub keys {} |
| 3214 | # CONTEXT sub keys {} |
| 3215 | no warnings; |
| 3216 | my($r1, %h1, $res); |
| 3217 | our($r2, %h2); |
| 3218 | CORE::keys %h1; |
| 3219 | CORE::keys(%h1) / 2; |
| 3220 | $res = CORE::keys %h1; |
| 3221 | $res = CORE::keys %h2; |
| 3222 | $res = CORE::keys %$r1; |
| 3223 | $res = CORE::keys %$r2; |
| 3224 | $res = CORE::keys(%h1) / 2 - 1; |
| 3225 | $res = CORE::keys(%h2) / 2 - 1; |
| 3226 | $res = CORE::keys(%$r1) / 2 - 1; |
| 3227 | $res = CORE::keys(%$r2) / 2 - 1; |
| 3228 | #### |
| 3229 | # concat: STACKED: ambiguity between .= and optimised nested |
| 3230 | my($a, $b); |
| 3231 | $b = $a . $a . $a; |
| 3232 | (($a .= $a) .= $a) .= $a; |
| 3233 | #### |
| 3234 | # multiconcat: $$ within string |
| 3235 | my($a, $x); |
| 3236 | $x = "${$}abc"; |
| 3237 | $x = "\$$a"; |
| 3238 | #### |
| 3239 | # single state aggregate assignment |
| 3240 | # CONTEXT use feature "state"; |
| 3241 | state @a = (1, 2, 3); |
| 3242 | state %h = ('a', 1, 'b', 2); |
| 3243 | #### |
| 3244 | # state var with attribute |
| 3245 | # CONTEXT use feature "state"; |
| 3246 | state $x :shared; |
| 3247 | state $y :shared = 1; |
| 3248 | state @a :shared; |
| 3249 | state @b :shared = (1, 2); |
| 3250 | state %h :shared; |
| 3251 | state %i :shared = ('a', 1, 'b', 2); |
| 3252 | #### |
| 3253 | # \our @a shouldn't be a list |
| 3254 | my $r = \our @a; |
| 3255 | my(@l) = \our((@b)); |
| 3256 | @l = \our(@c, @d); |
| 3257 | #### |
| 3258 | # postfix $# |
| 3259 | our(@b, $s, $l); |
| 3260 | $l = (\my @a)->$#*; |
| 3261 | (\@b)->$#* = 1; |
| 3262 | ++(\my @c)->$#*; |
| 3263 | $l = $#a; |
| 3264 | $#a = 1; |
| 3265 | $l = $#b; |
| 3266 | $#b = 1; |
| 3267 | my $r; |
| 3268 | $l = $r->$#*; |
| 3269 | $r->$#* = 1; |
| 3270 | $l = $#{@$r;}; |
| 3271 | $#{$r;} = 1; |
| 3272 | $l = $s->$#*; |
| 3273 | $s->$#* = 1; |
| 3274 | $l = $#{@$s;}; |
| 3275 | $#{$s;} = 1; |
| 3276 | #### |
| 3277 | # TODO doesn't preserve backslash |
| 3278 | my @a; |
| 3279 | my $s = "$a[0]\[1]"; |
| 3280 | #### |
| 3281 | # GH #17301 aux_list() sometimes returned wrong #args |
| 3282 | my($r, $h); |
| 3283 | $r = $h->{'i'}; |
| 3284 | $r = $h->{'i'}{'j'}; |
| 3285 | $r = $h->{'i'}{'j'}{'k'}; |
| 3286 | $r = $h->{'i'}{'j'}{'k'}{'l'}; |
| 3287 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}; |
| 3288 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}; |
| 3289 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}; |
| 3290 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}{'p'}; |
| 3291 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}{'p'}{'q'}; |
| 3292 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}{'p'}{'q'}{'r'}; |
| 3293 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}{'p'}{'q'}{'r'}{'s'}; |
| 3294 | $r = $h->{'i'}{'j'}{'k'}{'l'}{'m'}{'n'}{'o'}{'p'}{'q'}{'r'}{'s'}{'t'}; |
| 3295 | #### |
| 3296 | # chained comparison |
| 3297 | my($a, $b, $c, $d, $e, $f, $g); |
| 3298 | $a = $b gt $c >= $d; |
| 3299 | $a = $b < $c <= $d > $e; |
| 3300 | $a = $b == $c != $d; |
| 3301 | $a = $b eq $c ne $d == $e; |
| 3302 | $a = $b << $c < $d << $e <= $f << $g; |
| 3303 | $a = int $b < int $c <= int $d; |
| 3304 | $a = ($b < $c) < ($d < $e) <= ($f < $g); |
| 3305 | $a = ($b == $c) < ($d == $e) <= ($f == $g); |
| 3306 | $a = ($b & $c) < ($d & $e) <= ($f & $g); |
| 3307 | $a = $b << $c == $d << $e != $f << $g; |
| 3308 | $a = int $b == int $c != int $d; |
| 3309 | $a = $b < $c == $d < $e != $f < $g; |
| 3310 | $a = ($b == $c) == ($d == $e) != ($f == $g); |
| 3311 | $a = ($b & $c) == ($d & $e) != ($f & $g); |
| 3312 | $a = $b << ($c < $d <= $e); |
| 3313 | $a = int($c < $d <= $e); |
| 3314 | $a = $b < ($c < $d <= $e); |
| 3315 | $a = $b == $c < $d <= $e; |
| 3316 | $a = $b & $c < $d <= $e; |
| 3317 | $a = $b << ($c == $d != $e); |
| 3318 | $a = int($c == $d != $e); |
| 3319 | $a = $b < ($c == $d != $e); |
| 3320 | $a = $b == ($c == $d != $e); |
| 3321 | $a = $b & $c == $d != $e; |
| 3322 | #### |
| 3323 | # try/catch |
| 3324 | # CONTEXT use feature 'try'; no warnings 'experimental::try'; |
| 3325 | try { |
| 3326 | FIRST(); |
| 3327 | } |
| 3328 | catch($var) { |
| 3329 | SECOND(); |
| 3330 | } |
| 3331 | #### |
| 3332 | # CONTEXT use feature 'try'; no warnings 'experimental::try'; |
| 3333 | try { |
| 3334 | FIRST(); |
| 3335 | } |
| 3336 | catch($var) { |
| 3337 | my $x; |
| 3338 | SECOND(); |
| 3339 | } |
| 3340 | #### |
| 3341 | # CONTEXT use feature 'try'; no warnings 'experimental::try'; |
| 3342 | try { |
| 3343 | FIRST(); |
| 3344 | } |
| 3345 | catch($var) { |
| 3346 | SECOND(); |
| 3347 | } |
| 3348 | finally { |
| 3349 | THIRD(); |
| 3350 | } |
| 3351 | #### |
| 3352 | # defer blocks |
| 3353 | # CONTEXT use feature "defer"; no warnings 'experimental::defer'; |
| 3354 | defer { |
| 3355 | $a = 123; |
| 3356 | } |
| 3357 | #### |
| 3358 | # builtin:: functions |
| 3359 | # CONTEXT no warnings 'experimental::builtin'; |
| 3360 | my $x; |
| 3361 | $x = builtin::is_bool(undef); |
| 3362 | $x = builtin::is_weak(undef); |
| 3363 | builtin::weaken($x); |
| 3364 | builtin::unweaken($x); |
| 3365 | $x = builtin::blessed(undef); |
| 3366 | $x = builtin::refaddr(undef); |
| 3367 | $x = builtin::reftype(undef); |
| 3368 | $x = builtin::ceil($x); |
| 3369 | $x = builtin::floor($x); |
| 3370 | $x = builtin::is_tainted($x); |
| 3371 | #### |
| 3372 | # boolean true preserved |
| 3373 | my $x = !0; |
| 3374 | #### |
| 3375 | # boolean false preserved |
| 3376 | my $x = !1; |
| 3377 | #### |
| 3378 | # const NV: NV-ness preserved |
| 3379 | my(@x) = (-2.0, -1.0, -0.0, 0.0, 1.0, 2.0); |
| 3380 | #### |
| 3381 | # PADSV_STORE optimised my should be handled |
| 3382 | () = (my $s = 1); |
| 3383 | #### |
| 3384 | # PADSV_STORE optimised state should be handled |
| 3385 | # CONTEXT use feature "state"; |
| 3386 | () = (state $s = 1); |
| 3387 | #### |
| 3388 | # control transfer in RHS of assignment |
| 3389 | my $x; |
| 3390 | $x = (return 'ok'); |
| 3391 | $x //= (return 'ok'); |
| 3392 | $x = exit 42; |
| 3393 | $x //= exit 42; |