This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix lib/B/Deparse.t that assumed '.' in @INC
[perl5.git] / lib / B / Deparse.t
index 1f2efdd..7eeb4f8 100644 (file)
@@ -7,13 +7,13 @@ BEGIN {
         print "1..0 # Skip -- Perl configured without B module\n";
         exit 0;
     }
-    require 'test.pl';
+    require './test.pl';
 }
 
 use warnings;
 use strict;
 
-my $tests = 34; # not counting those in the __DATA__ section
+my $tests = 46; # not counting those in the __DATA__ section
 
 use B::Deparse;
 my $deparse = B::Deparse->new();
@@ -87,7 +87,12 @@ EOC
        $regex =~ s/\s+/\\s+/g;
        $regex = '^\{\s*' . $regex . '\s*\}$';
 
-        like($deparsed, qr/$regex/, $desc);
+        like($deparsed, qr/$regex/, $desc)
+            or diag "=============================================\n"
+                  . "CODE:\n--------\n$input\n--------\n"
+                  . "EXPECTED:\n--------\n{\n$expected\n}\n--------\n"
+                  . "GOT:\n--------\n$deparsed\n--------\n"
+                  . "=============================================\n";
     }
 }
 
@@ -128,7 +133,7 @@ $b = quotemeta <<'EOF';
 BEGIN { $^I = ".bak"; }
 BEGIN { $^W = 1; }
 BEGIN { $/ = "\n"; $\ = "\n"; }
-LINE: while (defined($_ = <ARGV>)) {
+LINE: while (defined($_ = readline ARGV)) {
     chomp $_;
     our(@F) = split(' ', $_, 0);
     '???';
@@ -140,7 +145,7 @@ like($a, qr/$b/,
 
 $a = `$^X $path "-MO=Deparse" -e "use constant PI => 4" 2>&1`;
 $a =~ s/-e syntax OK\n//g;
-is($a, "();\nuse constant ('PI', 4);\n",
+is($a, "use constant ('PI', 4);\n",
    "Proxy Constant Subroutines must not show up as (incorrect) prototypes");
 
 #Re: perlbug #35857, patch #24505
@@ -188,7 +193,6 @@ EOFCODE
 $a = `$^X $path "-MO=Deparse" -e "sub ::::{}sub ::::::{}" 2>&1`;
 $a =~ s/-e syntax OK\n//g;
 is($a, <<'EOCODG', "sub :::: and sub ::::::");
-();
 sub :::: {
     
 }
@@ -225,7 +229,6 @@ $a =
   `$^X $path "-MO=Deparse" -e "BEGIN{*CORE::GLOBAL::require=sub{1}}" 2>&1`;
 $a =~ s/-e syntax OK\n//g;
 is($a, <<'EOCODF', "CORE::GLOBAL::require override causing panick");
-();
 sub BEGIN {
     *CORE::GLOBAL::require = sub {
         1;
@@ -301,6 +304,18 @@ $foo
 .
 EOCODM
 
+is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+           prog => "{ my \$x; format =\n\@\n\$x\n.\n}"),
+   <<'EOCODN', 'formats nested inside blocks';
+{
+    my $x;
+    format STDOUT =
+@
+$x
+.
+}
+EOCODN
+
 # CORE::format
 $a = readpipe qq`$^X $path "-MO=Deparse" -e "use feature q|:all|;`
              .qq` my sub format; CORE::format =" -e. 2>&1`;
@@ -321,23 +336,52 @@ is($a, <<'EOCODI', 'no extra output when deparsing foo()');
 foo();
 EOCODI
 
+# Sub calls compiled before importation
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'BEGIN {
+                       require Test::More;
+                       Test::More::->import;
+                       is(*foo, *foo)
+                     }'),
+     qr/&is\(/,
+    'sub calls compiled before importation of prototype subs';
+
+# [perl #121050] Prototypes with whitespace
+is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+           prog => <<'EOCODO'),
+sub _121050(\$ \$) { }
+_121050($a,$b);
+sub _121050empty( ) {}
+() = _121050empty() + 1;
+EOCODO
+   <<'EOCODP', '[perl #121050] prototypes with whitespace';
+sub _121050 (\$ \$) {
+    
+}
+_121050 $a, $b;
+sub _121050empty ( ) {
+    
+}
+() = _121050empty + 1;
+EOCODP
+
 # CORE::no
 $a = readpipe qq`$^X $path "-MO=Deparse" -Xe `
              .qq`"use feature q|:all|; my sub no; CORE::no less" 2>&1`;
-like($a, qr/my sub no;\nCORE::no less;/,
+like($a, qr/my sub no;\n.*CORE::no less;/s,
     'CORE::no after my sub no');
 
 # CORE::use
 $a = readpipe qq`$^X $path "-MO=Deparse" -Xe `
              .qq`"use feature q|:all|; my sub use; CORE::use less" 2>&1`;
-like($a, qr/my sub use;\nCORE::use less;/,
+like($a, qr/my sub use;\n.*CORE::use less;/s,
     'CORE::use after my sub use');
 
 # CORE::__DATA__
 $a = readpipe qq`$^X $path "-MO=Deparse" -Xe `
              .qq`"use feature q|:all|; my sub __DATA__; `
              .qq`CORE::__DATA__" 2>&1`;
-like($a, qr/my sub __DATA__;\n.*\nCORE::__DATA__/s,
+like($a, qr/my sub __DATA__;\n.*CORE::__DATA__/s,
     'CORE::__DATA__ after my sub __DATA__');
 
 # sub declarations
@@ -347,6 +391,16 @@ like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
            prog => 'sub f($); sub f($){}'),
      qr/sub f\s*\(\$\)\s*\{\s*\}/,
     'predeclared prototyped subs';
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+           prog => 'use Scalar::Util q-weaken-;
+                    sub f($);
+                    BEGIN { weaken($_=\$::{f}) }'),
+     qr/sub f\s*\(\$\)\s*;/,
+    'prototyped stub with weak reference to the stash entry';
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+           prog => 'sub f () { 42 }'),
+     qr/sub f\s*\(\)\s*\{\s*42;\s*\}/,
+    'constant perl sub declaration';
 
 # BEGIN blocks
 SKIP : {
@@ -412,6 +466,11 @@ sub BEGIN {
 }
 EOCODL
 
+# BEGIN blocks should not be called __ANON__
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'sub BEGIN { } CHECK { delete $::{BEGIN} }'),
+     qr/sub BEGIN/, 'anonymised BEGIN';
+
 # [perl #115066]
 my $prog = 'use constant FOO => do { 1 }; no overloading; die';
 $a = readpipe qq`$^X $path "-MO=-qq,Deparse" -e "$prog" 2>&1`;
@@ -423,16 +482,51 @@ no overloading;
 die;
 EOCODK
 
+# BEGIN blocks inside predeclared subs
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => '
+                 sub run_tests;
+                 run_tests();
+                 sub run_tests { BEGIN { } die }'),
+     qr/sub run_tests \{\s*sub BEGIN/,
+    'BEGIN block inside predeclared sub';
+
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'package foo; use overload qr=>sub{}'),
+     qr/package foo;\s*use overload/,
+    'package, then use';
+
 like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
              prog => 'use feature lexical_subs=>; my sub f;sub main::f{}'),
      qr/^sub main::f \{/m,
     'sub decl when lex sub is in scope';
 
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'sub foo{foo()}'),
+     qr/^sub foo \{\s+foo\(\)/m,
+    'recursive sub';
+
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'use feature lexical_subs=>state=>;
+                      state sub sb5; sub { sub sb5 { } }'),
+     qr/sub \{\s*\(\);\s*sub sb5 \{/m,
+    'state sub in anon sub but declared outside';
+
+is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+             prog => 'BEGIN { $::{f}=\!0 }'),
+   "sub BEGIN {\n    \$main::{'f'} = \\1;\n}\n",
+   '&PL_sv_yes constant (used to croak)';
+
 is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path, '-T' ],
            prog => '$x =~ (1?/$a/:0)'),
   '$x =~ ($_ =~ /$a/);'."\n",
   '$foo =~ <branch-folded match> under taint mode';
 
+unlike runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path, '-w' ],
+               prog => 'BEGIN { undef &foo }'),
+       qr'Use of uninitialized value',
+      'no warnings for undefined sub';
+
 done_testing($tests);
 
 __DATA__
@@ -453,6 +547,14 @@ tr/\x{345}/\x{370}/;
     2;
 }
 ####
+# List of constants in void context
+# CONTEXT no warnings;
+(1,2,3);
+0;
+>>>>
+'???', '???', '???';
+0;
+####
 # Lexical and simple arithmetic
 my $test;
 ++$test and $test /= 2;
@@ -501,6 +603,7 @@ print $main::x;
 # lexical and package arrays
 my @x;
 print $main::x[1];
+print \my @a;
 ####
 # lexical and package hashes
 my %x;
@@ -530,10 +633,39 @@ local our($rhu, $barb);
 ####
 # <>
 my $foo;
-$_ .= <ARGV> . <$foo>;
+$_ .= <> . <ARGV> . <$foo>;
+<$foo>;
+<${foo}>;
+<$ foo>;
+>>>>
+my $foo;
+$_ .= readline(ARGV) . readline(ARGV) . readline($foo);
+readline $foo;
+glob $foo;
+glob $foo;
+####
+# readline
+readline 'FH';
+readline *$_;
+readline *{$_};
+readline ${"a"};
+>>>>
+readline 'FH';
+readline *$_;
+readline *{$_;};
+readline ${'a';};
+####
+# <<>>
+$_ = <<>>;
 ####
 # \x{}
 my $foo = "Ab\x{100}\200\x{200}\237Cd\000Ef\x{1000}\cA\x{2000}\cZ";
+my $bar = "\x{100}";
+####
+# Latin-1 chars
+# TODO ? ord("A") != 65 && "EBCDIC"
+my $baz = "B\366\x{100}";
+my $bba = qr/B\366\x{100}/;
 ####
 # s///e
 s/x/'y';/e;
@@ -624,6 +756,11 @@ foreach state $i (1, 2) {
     state $z = 1;
 }
 ####
+# foreach with sub call
+foreach $_ (hcaerof()) {
+    ();
+}
+####
 # reverse sort
 my @x;
 print reverse sort(@x);
@@ -648,12 +785,38 @@ print $_ foreach (reverse 1, 2..5);
 our @ary;
 @ary = split(' ', 'foo', 0);
 ####
+my @ary;
+@ary = split(' ', 'foo', 0);
+####
 # Split to our array
 our @array = split(//, 'foo', 0);
 ####
 # Split to my array
 my @array  = split(//, 'foo', 0);
 ####
+our @array;
+my $c;
+@array = split(/x(?{ $c++; })y/, 'foo', 0);
+####
+my($x, $y, $p);
+our $c;
+($x, $y) = split(/$p(?{ $c++; })y/, 'foo', 2);
+####
+our @ary;
+my $pat;
+@ary = split(/$pat/, 'foo', 0);
+####
+my @ary;
+our $pat;
+@ary = split(/$pat/, 'foo', 0);
+####
+our @array;
+my $pat;
+local @array = split(/$pat/, 'foo', 0);
+####
+our $pat;
+my @array  = split(/$pat/, 'foo', 0);
+####
 # bug #40055
 do { () }; 
 ####
@@ -706,6 +869,14 @@ our @bar;
 (foo { @bar } 1), foo();
 foo { @bar } 1 xor foo();
 ####
+# indirops with blocks
+# CONTEXT use 5.01;
+print {*STDOUT;} 'foo';
+printf {*STDOUT;} 'foo';
+say {*STDOUT;} 'foo';
+system {'foo';} '-foo';
+exec {'foo';} '-foo';
+####
 # SKIP ?$] < 5.010 && "say not implemented on this Perl version"
 # CONTEXT use feature ':5.10';
 # say
@@ -721,7 +892,7 @@ say 'foo';
 use 5.10.0;
 say 'foo';
 >>>>
-no feature;
+no feature ':all';
 use feature ':5.10';
 say 'foo';
 ####
@@ -739,7 +910,7 @@ say 'foo';
 use 5.10.0;
 say 'foo';
 >>>>
-no feature;
+no feature ':all';
 use feature ':5.10';
 say 'foo';
 ####
@@ -766,7 +937,7 @@ __SUB__;
 use 5.15.0;
 __SUB__;
 >>>>
-no feature;
+no feature ':all';
 use feature ':5.16';
 __SUB__;
 ####
@@ -784,7 +955,7 @@ __SUB__;
 use 5.15.0;
 __SUB__;
 >>>>
-no feature;
+no feature ':all';
 use feature ':5.16';
 __SUB__;
 ####
@@ -1125,6 +1296,20 @@ print /$s[1]/;
 # /$#a/
 print /$#main::a/;
 ####
+# /@array/
+our @a;
+my @b;
+print /@a/;
+print /@b/;
+print qr/@a/;
+print qr/@b/;
+####
+# =~ QR_CONSTANT
+use constant QR_CONSTANT => qr/a/soupmix;
+'' =~ QR_CONSTANT;
+>>>>
+'' =~ /a/impsux;
+####
 # $lexical =~ //
 my $x;
 $x =~ //;
@@ -1163,11 +1348,67 @@ print /a/u, s/b/c/u;
     print /a/d, s/b/c/d;
 }
 {
-    no feature;
+    no feature ':all';
     use feature ':5.12';
     print /a/d, s/b/c/d;
 }
 ####
+# all the flags (qr//)
+$_ = qr/X/m;
+$_ = qr/X/s;
+$_ = qr/X/i;
+$_ = qr/X/x;
+$_ = qr/X/p;
+$_ = qr/X/o;
+$_ = qr/X/u;
+$_ = qr/X/a;
+$_ = qr/X/l;
+$_ = qr/X/n;
+####
+use feature 'unicode_strings';
+$_ = qr/X/d;
+####
+# all the flags (m//)
+/X/m;
+/X/s;
+/X/i;
+/X/x;
+/X/p;
+/X/o;
+/X/u;
+/X/a;
+/X/l;
+/X/n;
+/X/g;
+/X/cg;
+####
+use feature 'unicode_strings';
+/X/d;
+####
+# all the flags (s///)
+s/X//m;
+s/X//s;
+s/X//i;
+s/X//x;
+s/X//p;
+s/X//o;
+s/X//u;
+s/X//a;
+s/X//l;
+s/X//n;
+s/X//g;
+s/X/'';/e;
+s/X//r;
+####
+use feature 'unicode_strings';
+s/X//d;
+####
+# all the flags (tr///)
+tr/X/Y/c;
+tr/X//d;
+tr/X//s;
+tr/X//r;
+####
 # [perl #119807] s//\(3)/ge should not warn when deparsed (\3 warns)
 s/foo/\(3);/eg;
 ####
@@ -1212,6 +1453,10 @@ s/a(??{ die $b; })a//;
 s/$a(??{ die $b; })//;
 s/@a(??{ die $b; })//;
 ####
+# /(?x)<newline><tab>/
+/(?x)
+       /;
+####
 # y///r
 tr/a/b/r + $a =~ tr/p/q/r;
 ####
@@ -1220,8 +1465,13 @@ tr/a/b/r + $a =~ tr/p/q/r;
 ####
 # [perl #90898]
 <a,>;
+glob 'a,';
+>>>>
+glob 'a,';
+glob 'a,';
 ####
 # [perl #91008]
+# SKIP ?$] >= 5.023 && "autoderef deleted in this Perl version"
 # CONTEXT no warnings 'experimental::autoderef';
 each $@;
 keys $~;
@@ -1301,7 +1551,7 @@ CORE::given ($x) {
 CORE::evalbytes '';
 () = CORE::__SUB__;
 >>>>
-no feature;
+no feature ':all';
 use feature ':default';
 CORE::say $_;
 CORE::state $x;
@@ -1380,10 +1630,10 @@ print;
 >>>>
 use feature 'current_sub', 'evalbytes';
 print $_;
-no feature;
+no feature ':all';
 use feature ':default';
 print $_;
-no feature;
+no feature ':all';
 use feature ':5.12';
 print $_;
 no feature 'unicode_strings';
@@ -1394,7 +1644,7 @@ my @x;
 @x = ($#{`}, $#{~}, $#{!}, $#{@}, $#{$}, $#{%}, $#{^}, $#{&}, $#{*});
 @x = ($#{(}, $#{)}, $#{[}, $#{{}, $#{]}, $#{}}, $#{'}, $#{"}, $#{,});
 @x = ($#{<}, $#{.}, $#{>}, $#{/}, $#{?}, $#{=}, $#+, $#{\}, $#{|}, $#-);
-@x = ($#{;}, $#{:});
+@x = ($#{;}, $#{:}, $#{1}), $#_;
 ####
 # ${#} interpolated
 # It's a known TODO that warnings are deparsed as bits, not textually.
@@ -1406,6 +1656,7 @@ no warnings;
 /${|}/;
 /${)}/;
 /${(}${|}${)}/;
+/@{+}@{-}/;
 ####
 # ()[...]
 my(@a) = ()[()];
@@ -1487,6 +1738,18 @@ CORE::do({});
 () = (-w $_) + 3;
 () = (-x $_) + 3;
 ####
+# require(foo()) and do(foo())
+require (foo());
+do (foo());
+goto (foo());
+CORE::dump (foo());
+last (foo());
+next (foo());
+redo (foo());
+####
+# require vstring
+require v5.16;
+####
 # [perl #97476] not() *does* follow the llafr
 $_ = ($a xor not +($1 || 2) ** 2);
 ####
@@ -1709,36 +1972,28 @@ my($a, $b, $c) = @_;
 ####
 # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version"
 # lexical subroutine
-use feature 'lexical_subs';
+# CONTEXT use feature 'lexical_subs';
 no warnings "experimental::lexical_subs";
 my sub f {}
 print f();
 >>>>
-use feature 'lexical_subs';
-BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUUU\005"}
+BEGIN {${^WARNING_BITS} = "\x54\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x54\x55\x55\x55"}
 my sub f {
-    BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUU\005"}
     
 }
-BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUU\005"}
 print f();
 ####
 # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version"
 # lexical "state" subroutine
-use feature 'state', 'lexical_subs';
+# CONTEXT use feature 'state', 'lexical_subs';
 no warnings 'experimental::lexical_subs';
 state sub f {}
 print f();
 >>>>
-use feature 'lexical_subs';
-BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUUU\005"}
-CORE::state sub f {
-    BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUU\005"}
-    use feature 'state';
+BEGIN {${^WARNING_BITS} = "\x54\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x54\x55\x55\x55"}
+state sub f {
     
 }
-BEGIN {${^WARNING_BITS} = "TUUUUUUUUUUUUTUU\005"}
-use feature 'state';
 print f();
 ####
 # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version"
@@ -1750,7 +2005,7 @@ print f();
     {
       foo();
       my sub b;
-      b();
+      b ;
       main::b();
       &main::b;
       &main::b();
@@ -1761,23 +2016,117 @@ print f();
   b();
 }
 ####
+# self-referential lexical subroutine
+# CONTEXT use feature 'lexical_subs', 'state'; no warnings 'experimental::lexical_subs';
+();
+state sub sb2;
+sub sb2 {
+    sb2 ;
+}
+####
+# lexical subroutine with outer declaration and inner definition
+# CONTEXT use feature 'lexical_subs'; no warnings 'experimental::lexical_subs';
+();
+my sub f;
+my sub g {
+    ();
+    sub f { }
+}
+####
+# TODO only partially fixed
+# lexical state subroutine with outer declaration and inner definition
+# CONTEXT use feature 'lexical_subs', 'state'; no warnings 'experimental::lexical_subs';
+();
+state sub sb4;
+state sub a {
+    ();
+    sub sb4 { }
+}
+state sub sb5;
+sub {
+    ();
+    sub sb5 { }
+} ;
+####
 # Elements of %# should not be confused with $#{ array }
 () = ${#}{'foo'};
 ####
-# $; [perl #12335]
+# $; [perl #123357]
 $_ = $;;
 do {
     $;
 };
 ####
-# [perl #121050] Prototypes with whitespace
-sub _121050(\$ \$) { }
-_121050($a,$b);
-sub _121050empty( ) {}
-() = _121050empty() + 1;
+# Ampersand calls and scalar context
+# OPTIONS -P
+package prototest;
+sub foo($$);
+foo(bar(),baz());
 >>>>
-_121050 $a, $b;
-() = _121050empty + 1;
+package prototest;
+&foo(scalar bar(), scalar baz());
+####
+# coderef2text and prototyped sub calls [perl #123435]
+is 'foo', 'oo';
+####
+# prototypes with unary precedence
+package prototest;
+sub dollar($) {}
+sub optdollar(;$) {}
+sub optoptdollar(;;$) {}
+sub splat(*) {}
+sub optsplat(;*) {}
+sub optoptsplat(;;*) {}
+sub bar(_) {}
+sub optbar(;_) {}
+sub optoptbar(;;_) {}
+sub plus(+) {}
+sub optplus(;+) {}
+sub optoptplus(;;+) {}
+sub wack(\$) {}
+sub optwack(;\$) {}
+sub optoptwack(;;\$) {}
+sub wackbrack(\[$]) {}
+sub optwackbrack(;\[$]) {}
+sub optoptwackbrack(;;\[$]) {}
+dollar($a < $b);
+optdollar($a < $b);
+optoptdollar($a < $b);
+splat($a < $b);     # Some of these deparse with ‘&’; if that changes, just
+optsplat($a < $b);  # change the tests.
+optoptsplat($a < $b);
+bar($a < $b);
+optbar($a < $b);
+optoptbar($a < $b);
+plus($a < $b);
+optplus($a < $b);
+optoptplus($a < $b);
+wack($a = $b);
+optwack($a = $b);
+optoptwack($a = $b);
+wackbrack($a = $b);
+optwackbrack($a = $b);
+optoptwackbrack($a = $b);
+>>>>
+package prototest;
+dollar($a < $b);
+optdollar($a < $b);
+optoptdollar($a < $b);
+&splat($a < $b);
+&optsplat($a < $b);
+&optoptsplat($a < $b);
+bar($a < $b);
+optbar($a < $b);
+optoptbar($a < $b);
+&plus($a < $b);
+&optplus($a < $b);
+&optoptplus($a < $b);
+&wack(\($a = $b));
+&optwack(\($a = $b));
+&optoptwack(\($a = $b));
+&wackbrack(\($a = $b));
+&optwackbrack(\($a = $b));
+&optoptwackbrack(\($a = $b));
 ####
 # ensure aelemfast works in the range -128..127 and that there's no
 # funky edge cases
@@ -2062,3 +2411,202 @@ $_ = join $foo, pos
 >>>>
 my $foo;
 $_ = join('???', pos $_);
+####
+# exists $a[0]
+our @a;
+exists $a[0];
+####
+# my @a; exists $a[0]
+my @a;
+exists $a[0];
+####
+# delete $a[0]
+our @a;
+delete $a[0];
+####
+# my @a; delete $a[0]
+my @a;
+delete $a[0];
+####
+# $_[0][$_[1]]
+$_[0][$_[1]];
+####
+# f($a[0]);
+my @a;
+f($a[0]);
+####
+#qr/\Q$h{'key'}\E/;
+my %h;
+qr/\Q$h{'key'}\E/;
+####
+# my $x = "$h{foo}";
+my %h;
+my $x = "$h{'foo'}";
+####
+# weird constant hash key
+my %h;
+my $x = $h{"\000\t\x{100}"};
+####
+# multideref and packages
+package foo;
+my(%bar) = ('a', 'b');
+our(@bar) = (1, 2);
+$bar{'k'} = $bar[200];
+$main::bar{'k'} = $main::bar[200];
+$foo::bar{'k'} = $foo::bar[200];
+package foo2;
+$bar{'k'} = $bar[200];
+$main::bar{'k'} = $main::bar[200];
+$foo::bar{'k'} = $foo::bar[200];
+>>>>
+package foo;
+my(%bar) = ('a', 'b');
+our(@bar) = (1, 2);
+$bar{'k'} = $bar[200];
+$main::bar{'k'} = $main::bar[200];
+$foo::bar{'k'} = $bar[200];
+package foo2;
+$bar{'k'} = $foo::bar[200];
+$main::bar{'k'} = $main::bar[200];
+$foo::bar{'k'} = $foo::bar[200];
+####
+# multideref and local
+my %h;
+local $h{'foo'}[0] = 1;
+####
+# multideref and exists
+my(%h, $i);
+my $e = exists $h{'foo'}[$i];
+####
+# multideref and delete
+my(%h, $i);
+my $e = delete $h{'foo'}[$i];
+####
+# multideref with leading expression
+my $r;
+my $x = +($r // [])->{'foo'}[0];
+####
+# multideref with complex middle index
+my(%h, $i, $j, $k);
+my $x = $h{'foo'}[$i + $j]{$k};
+####
+# multideref with trailing non-simple index that initially looks simple
+# (i.e. the constant "3")
+my($r, $i, $j, $k);
+my $x = +($r || {})->{'foo'}[$i + $j]{3 + $k};
+####
+# chdir
+chdir 'file';
+chdir FH;
+chdir;
+####
+# 5.22 bitops
+# CONTEXT use feature "bitwise"; no warnings "experimental::bitwise";
+$_ = $_ | $_;
+$_ = $_ & $_;
+$_ = $_ ^ $_;
+$_ = ~$_;
+$_ = $_ |. $_;
+$_ = $_ &. $_;
+$_ = $_ ^. $_;
+$_ = ~.$_;
+$_ |= $_;
+$_ &= $_;
+$_ ^= $_;
+$_ |.= $_;
+$_ &.= $_;
+$_ ^.= $_;
+####
+####
+# Should really use 'no warnings "experimental::signatures"',
+# but it doesn't yet deparse correctly.
+# anon subs used because this test framework doesn't deparse named subs
+# in the DATA code snippets.
+#
+# general signature
+no warnings;
+use feature 'signatures';
+my $x;
+sub ($a, $, $b = $glo::bal, $c = $a, $d = 'foo', $e = -37, $f = 0, $g = 1, $h = undef, $i = $a + 1, $j = /foo/, @) {
+    $x++;
+}
+;
+$x++;
+####
+# Signature and prototype
+no warnings;
+use feature 'signatures';
+my $x;
+sub ($a, $b) : prototype($$) {
+    $x++;
+}
+;
+$x++;
+####
+# Signature and prototype and attrs
+no warnings;
+use feature 'signatures';
+my $x;
+sub ($a, $b) : prototype($$) lvalue {
+    $x++;
+}
+;
+$x++;
+####
+# Signature and attrs
+no warnings;
+use feature 'signatures';
+my $x;
+sub ($a, $b) : lvalue method {
+    $x++;
+}
+;
+$x++;
+####
+# named array slurp, null body
+no warnings;
+use feature 'signatures';
+sub (@a) {
+    ;
+}
+;
+####
+# named hash slurp
+no warnings;
+use feature 'signatures';
+sub ($key, %h) {
+    $h{$key};
+}
+;
+####
+# anon hash slurp
+no warnings;
+use feature 'signatures';
+sub ($a, %) {
+    $a;
+}
+;
+####
+# parenthesised default arg
+no warnings;
+use feature 'signatures';
+sub ($a, $b = (/foo/), $c = 1) {
+    $a + $b + $c;
+}
+;
+####
+# parenthesised default arg with TARGMY
+no warnings;
+use feature 'signatures';
+sub ($a, $b = ($a + 1), $c = 1) {
+    $a + $b + $c;
+}
+;
+####
+# empty default
+no warnings;
+use feature 'signatures';
+sub ($a, $=) {
+    $a;
+}
+;