This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
'Prototype after' and 'Illegal character' warnings should both pretty print the proto...
[perl5.git] / t / lib / warnings / op
index 1e39c0e..c38bcde 100644 (file)
@@ -1,34 +1,11 @@
   op.c         AOK
 
-     "my" variable %s masks earlier declaration in same scope
-       my $x;
-       my $x ;
-
-     Variable "%s" may be unavailable 
-       sub x {
-           my $x;
-           sub y {
-               $x
-           }
-       }
-
-     Variable "%s" will not stay shared 
-       sub x {
-           my $x;
-           sub y {
-               sub { $x }
-           }
-       }
+     Use of my $_ is experimental
+       my $_ ;
 
      Found = in conditional, should be ==
        1 if $a = 1 ;
 
-     Use of implicit split to @_ is deprecated
-       split ;
-
-     Use of implicit split to @_ is deprecated
-       $a = split ;
-
      Useless use of time in void context
      Useless use of a variable in void context
      Useless use of a constant in void context
      defined(%hash) is deprecated
        (Maybe you should just omit the defined()?)
        my %h ; defined %h ;
-    
+
+     "my %s" used in sort comparison
+
+     $[ used in comparison (did you mean $] ?)
+
+     length() used on @array (did you mean "scalar(@array)"?)
+     length() used on %hash (did you mean "scalar(keys %hash)"?)
+
      /---/ should probably be written as "---"
         join(/---/, @foo);
 
         fred() ; sub fred ($$) {}
 
 
-    Package `%s' not found (did you use the incorrect case?)
+    Package '%s' not found (did you use the incorrect case?)
 
     Use of /g modifier is meaningless in split
 
         sub fred() ;
         sub fred($) {}
 
-    %s never introduced                [pad_leavemy]   TODO
-    Runaway prototype          [newSUB]        TODO
     oops: oopsAV               [oopsAV]        TODO
     oops: oopsHV               [oopsHV]        TODO
     
 __END__
 # op.c
-use warnings 'misc' ;
-my $x ;
-my $x ;
-my $y = my $y ;
-no warnings 'misc' ;
-my $x ;
-my $y ;
-EXPECT
-"my" variable $x masks earlier declaration in same scope at - line 4.
-"my" variable $y masks earlier declaration in same statement at - line 5.
-########
-# op.c
-use warnings 'closure' ;
-sub x {
-      my $x;
-      sub y {
-         $x
-      }
-   }
+use warnings 'experimental::lexical_topic' ;
+my $_;
+CORE::state $_;
+no warnings 'experimental::lexical_topic' ;
+my $_;
+CORE::state $_;
 EXPECT
-Variable "$x" will not stay shared at - line 7.
-########
-# op.c
-no warnings 'closure' ;
-sub x {
-      my $x;
-      sub y {
-         $x
-      }
-   }
-EXPECT
-
-########
-# op.c
-use warnings 'closure' ;
-sub x {
-      our $x;
-      sub y {
-         $x
-      }
-   }
-EXPECT
-
-########
-# op.c
-use warnings 'closure' ;
-sub x {
-      my $x;
-      sub y {
-         sub { $x }
-      }
-   }
-EXPECT
-Variable "$x" may be unavailable at - line 6.
-########
-# op.c
-no warnings 'closure' ;
-sub x {
-      my $x;
-      sub y {
-         sub { $x }
-      }
-   }
-EXPECT
-
+Use of my $_ is experimental at - line 3.
+Use of state $_ is experimental at - line 4.
 ########
 # op.c
 use warnings 'syntax' ;
 1 if $a = 1 ;
+1 if $a
+  = 1 ;
 no warnings 'syntax' ;
 1 if $a = 1 ;
+1 if $a
+  = 1 ;
 EXPECT
 Found = in conditional, should be == at - line 3.
+Found = in conditional, should be == at - line 4.
 ########
 # op.c
-use warnings 'deprecated' ;
-split ;
-no warnings 'deprecated' ;
-split ;
-EXPECT
-Use of implicit split to @_ is deprecated at - line 3.
-########
-# op.c
-use warnings 'deprecated' ;
-$a = split ;
-no warnings 'deprecated' ;
-$a = split ;
+use warnings 'syntax' ;
+use constant foo => 1;
+1 if $a = foo ;
+no warnings 'syntax' ;
+1 if $a = foo ;
 EXPECT
-Use of implicit split to @_ is deprecated at - line 3.
 ########
 # op.c
-use warnings 'deprecated';
 my (@foo, %foo);
 %main::foo->{"bar"};
 %foo->{"bar"};
@@ -236,18 +158,20 @@ $foo = {}; %$foo->{"bar"};
 $main::foo = []; @$main::foo->[34];
 $foo = []; @$foo->[34];
 EXPECT
+Using a hash as a reference is deprecated at - line 3.
 Using a hash as a reference is deprecated at - line 4.
-Using a hash as a reference is deprecated at - line 5.
+Using an array as a reference is deprecated at - line 5.
 Using an array as a reference is deprecated at - line 6.
-Using an array as a reference is deprecated at - line 7.
+Using a hash as a reference is deprecated at - line 7.
 Using a hash as a reference is deprecated at - line 8.
-Using a hash as a reference is deprecated at - line 9.
+Using an array as a reference is deprecated at - line 9.
 Using an array as a reference is deprecated at - line 10.
-Using an array as a reference is deprecated at - line 11.
 ########
 # op.c
-use warnings 'void' ; close STDIN ;
-1 x 3 ;                        # OP_REPEAT
+use warnings 'void' ; no warnings 'experimental::smartmatch'; close STDIN ;
+#line 2
+1 x 3 ;                        # OP_REPEAT (folded)
+(1) x 3 ;              # OP_REPEAT
                        # OP_GVSV
 wantarray ;            # OP_WANTARRAY
                        # OP_GV
@@ -298,7 +222,16 @@ eval { getgrnam 1 };       # OP_GGRNAM
 eval { getgrgid 1 };   # OP_GGRGID
 eval { getpwnam 1 };   # OP_GPWNAM
 eval { getpwuid 1 };   # OP_GPWUID
+prototype "foo";       # OP_PROTOTYPE
+$a ~~ $b;              # OP_SMARTMATCH
+$a <=> $b;             # OP_NCMP
+"dsatrewq";
+"diatrewq";
+"igatrewq";
+use 5.015;
+__SUB__                        # OP_RUNCV
 EXPECT
+Useless use of a constant ("111") in void context at - line 2.
 Useless use of repeat (x) in void context at - line 3.
 Useless use of wantarray in void context at - line 5.
 Useless use of reference-type operator in void context at - line 12.
@@ -336,6 +269,13 @@ Useless use of getgrnam in void context at - line 50.
 Useless use of getgrgid in void context at - line 51.
 Useless use of getpwnam in void context at - line 52.
 Useless use of getpwuid in void context at - line 53.
+Useless use of subroutine prototype in void context at - line 54.
+Useless use of smart match in void context at - line 55.
+Useless use of numeric comparison (<=>) in void context at - line 56.
+Useless use of a constant ("dsatrewq") in void context at - line 57.
+Useless use of a constant ("diatrewq") in void context at - line 58.
+Useless use of a constant ("igatrewq") in void context at - line 59.
+Useless use of __SUB__ in void context at - line 61.
 ########
 # op.c
 use warnings 'void' ; close STDIN ;
@@ -398,6 +338,7 @@ eval { getgrnam 1 };        # OP_GGRNAM
 eval { getgrgid 1 };   # OP_GGRGID
 eval { getpwnam 1 };   # OP_GPWNAM
 eval { getpwuid 1 };   # OP_GPWUID
+prototype "foo";       # OP_PROTOTYPE
 EXPECT
 ########
 # op.c
@@ -610,32 +551,68 @@ Useless use of a variable in void context at - line 6.
 use warnings 'void' ;
 "abc"; # OP_CONST
 7 ; # OP_CONST
+"x" . "y"; # optimized to OP_CONST
+2 + 2; # optimized to OP_CONST
+use constant U => undef;
+U;
+qq/"   \n/;
+5 || print "bad\n";    # test OPpCONST_SHORTCIRCUIT
+print "boo\n" if U;    # test OPpCONST_SHORTCIRCUIT
 no warnings 'void' ;
 "abc"; # OP_CONST
 7 ; # OP_CONST
+"x" . "y"; # optimized to OP_CONST
+2 + 2; # optimized to OP_CONST
 EXPECT
-Useless use of a constant in void context at - line 3.
-Useless use of a constant in void context at - line 4.
+Useless use of a constant ("abc") in void context at - line 3.
+Useless use of a constant (7) in void context at - line 4.
+Useless use of a constant ("xy") in void context at - line 5.
+Useless use of a constant (4) in void context at - line 6.
+Useless use of a constant (undef) in void context at - line 8.
+Useless use of a constant ("\"\t\n") in void context at - line 9.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings 'void' ;
+"àḆc"; # OP_CONST
+"Ẋ" . "ƴ"; # optimized to OP_CONST
+FOO;     # Bareword optimized to OP_CONST
+use constant ů => undef;
+ů;
+5 || print "bad\n";    # test OPpCONST_SHORTCIRCUIT
+print "boo\n" if ů;   # test OPpCONST_SHORTCIRCUIT
+no warnings 'void' ;
+"àḆc"; # OP_CONST
+"Ẋ" . "ƴ"; # optimized to OP_CONST
+EXPECT
+Useless use of a constant ("\340\x{1e06}c") in void context at - line 5.
+Useless use of a constant ("\x{1e8a}\x{1b4}") in void context at - line 6.
+Useless use of a constant ("\x{ff26}\x{ff2f}\x{ff2f}") in void context at - line 7.
+Useless use of a constant (undef) in void context at - line 9.
 ########
 # op.c
 #
 use warnings 'misc' ;
-my $a ; my @a = () ; my %a = () ; my $b = \@a ; my $c = \%a ;
+my $a ; my @a = () ; my %a = () ; my $b = \@a ; my $c = \%a ;my $d = 'test';
 @a =~ /abc/ ;
-@a =~ s/a/b/ ;
-@a =~ tr/a/b/ ;
+@a2 =~ s/a/b/ ;
+@a3 =~ tr/a/b/ ;
 @$b =~ /abc/ ;
 @$b =~ s/a/b/ ;
 @$b =~ tr/a/b/ ;
 %a =~ /abc/ ;
-%a =~ s/a/b/ ;
-%a =~ tr/a/b/ ;
+%a2 =~ s/a/b/ ;
+%a3 =~ tr/a/b/ ;
 %$c =~ /abc/ ;
 %$c =~ s/a/b/ ;
 %$c =~ tr/a/b/ ;
+$d =~ tr/a/b/d ;
+$d2 =~ tr/a/bc/;
+$d3 =~ tr//b/c;
 {
 no warnings 'misc' ;
-my $a ; my @a = () ; my %a = () ; my $b = \@a ; my $c = \%a ;
+my $a ; my @a = () ; my %a = () ; my $b = \@a ; my $c = \%a ; my $d = 'test';
 @a =~ /abc/ ;
 @a =~ s/a/b/ ;
 @a =~ tr/a/b/ ;
@@ -648,38 +625,56 @@ my $a ; my @a = () ; my %a = () ; my $b = \@a ; my $c = \%a ;
 %$c =~ /abc/ ;
 %$c =~ s/a/b/ ;
 %$c =~ tr/a/b/ ;
+$d =~ tr/a/b/d ;
+$d =~ tr/a/bc/ ;
+$d =~ tr//b/c;
 }
 EXPECT
-Applying pattern match (m//) to @array will act on scalar(@array) at - line 5.
-Applying substitution (s///) to @array will act on scalar(@array) at - line 6.
-Applying transliteration (tr///) to @array will act on scalar(@array) at - line 7.
+Applying pattern match (m//) to @a will act on scalar(@a) at - line 5.
+Applying substitution (s///) to @a2 will act on scalar(@a2) at - line 6.
+Applying transliteration (tr///) to @a3 will act on scalar(@a3) at - line 7.
 Applying pattern match (m//) to @array will act on scalar(@array) at - line 8.
 Applying substitution (s///) to @array will act on scalar(@array) at - line 9.
 Applying transliteration (tr///) to @array will act on scalar(@array) at - line 10.
-Applying pattern match (m//) to %hash will act on scalar(%hash) at - line 11.
-Applying substitution (s///) to %hash will act on scalar(%hash) at - line 12.
-Applying transliteration (tr///) to %hash will act on scalar(%hash) at - line 13.
+Applying pattern match (m//) to %a will act on scalar(%a) at - line 11.
+Applying substitution (s///) to %a2 will act on scalar(%a2) at - line 12.
+Applying transliteration (tr///) to %a3 will act on scalar(%a3) at - line 13.
 Applying pattern match (m//) to %hash will act on scalar(%hash) at - line 14.
 Applying substitution (s///) to %hash will act on scalar(%hash) at - line 15.
 Applying transliteration (tr///) to %hash will act on scalar(%hash) at - line 16.
-Can't modify private array in substitution (s///) at - line 6, near "s/a/b/ ;"
-BEGIN not safe after errors--compilation aborted at - line 18.
+Useless use of /d modifier in transliteration operator at - line 17.
+Replacement list is longer than search list at - line 18.
+Can't modify array dereference in substitution (s///) at - line 6, near "s/a/b/ ;"
+BEGIN not safe after errors--compilation aborted at - line 21.
 ########
 # op.c
-use warnings 'syntax' ;
+use warnings 'parenthesis' ;
 my $a, $b = (1,2);
-no warnings 'syntax' ;
+my @foo,%bar,  $quux; # there's a TAB here
+my $x, $y or print;
+no warnings 'parenthesis' ;
 my $c, $d = (1,2);
 EXPECT
 Parentheses missing around "my" list at - line 3.
+Parentheses missing around "my" list at - line 4.
 ########
 # op.c
-use warnings 'syntax' ;
+use warnings 'parenthesis' ;
+our $a, $b = (1,2);
+no warnings 'parenthesis' ;
+our $c, $d = (1,2);
+EXPECT
+Parentheses missing around "our" list at - line 3.
+########
+# op.c
+use warnings 'parenthesis' ;
 local $a, $b = (1,2);
-no warnings 'syntax' ;
+local *f, *g;
+no warnings 'parenthesis' ;
 local $c, $d = (1,2);
 EXPECT
 Parentheses missing around "local" list at - line 3.
+Parentheses missing around "local" list at - line 4.
 ########
 # op.c
 use warnings 'bareword' ;
@@ -696,28 +691,43 @@ Bareword found in conditional at - line 3.
 use warnings 'misc' ;
 open FH, "<abc" ;
 $x = 1 if $x = <FH> ;
+$x = 1 if $x
+     = <FH> ;
 no warnings 'misc' ;
 $x = 1 if $x = <FH> ;
+$x = 1 if $x
+     = <FH> ;
 EXPECT
 Value of <HANDLE> construct can be "0"; test with defined() at - line 4.
+Value of <HANDLE> construct can be "0"; test with defined() at - line 5.
 ########
 # op.c
 use warnings 'misc' ;
 opendir FH, "." ;
 $x = 1 if $x = readdir FH ;
+$x = 1 if $x
+    = readdir FH ;
 no warnings 'misc' ;
 $x = 1 if $x = readdir FH ;
+$x = 1 if $x
+    = readdir FH ;
 closedir FH ;
 EXPECT
 Value of readdir() operator can be "0"; test with defined() at - line 4.
+Value of readdir() operator can be "0"; test with defined() at - line 5.
 ########
 # op.c
 use warnings 'misc' ;
 $x = 1 if $x = <*> ;
+$x = 1 if $x
+    = <*> ;
 no warnings 'misc' ;
 $x = 1 if $x = <*> ;
+$x = 1 if $x
+    = <*> ;
 EXPECT
 Value of glob construct can be "0"; test with defined() at - line 3.
+Value of glob construct can be "0"; test with defined() at - line 4.
 ########
 # op.c
 use warnings 'misc' ;
@@ -747,13 +757,26 @@ EXPECT
 Value of readdir() operator can be "0"; test with defined() at - line 4.
 ########
 # op.c
+use warnings 'misc';
+open FH, "<abc";
+($_ = <FH>) // ($_ = 1);
+opendir DH, ".";
+%a = (1,2,3,4) ;
+EXPECT
+########
+# op.c
 use warnings 'redefine' ;
 sub fred {}
 sub fred {}
+sub fred { # warning should be for this line
+}
 no warnings 'redefine' ;
 sub fred {}
+sub fred {
+}
 EXPECT
 Subroutine fred redefined at - line 4.
+Subroutine fred redefined at - line 5.
 ########
 # op.c
 use warnings 'redefine' ;
@@ -765,18 +788,50 @@ EXPECT
 Constant subroutine fred redefined at - line 4.
 ########
 # op.c
-no warnings 'redefine' ;
 sub fred () { 1 }
 sub fred () { 2 }
 EXPECT
+Constant subroutine fred redefined at - line 3.
+########
+# op.c
+sub fred () { 1 }
+*fred = sub () { 2 };
+EXPECT
+Constant subroutine main::fred redefined at - line 3.
+########
+# op.c
+use feature "lexical_subs", "state";
+my sub fred () { 1 }
+sub fred { 2 };
+my sub george { 1 }
+sub george () { 2 } # should *not* produce redef warnings by default
+state sub phred () { 1 }
+sub phred { 2 };
+state sub jorge { 1 }
+sub jorge () { 2 } # should *not* produce redef warnings by default
+EXPECT
+The lexical_subs feature is experimental at - line 3.
+Prototype mismatch: sub fred () vs none at - line 4.
 Constant subroutine fred redefined at - line 4.
+The lexical_subs feature is experimental at - line 5.
+Prototype mismatch: sub george: none vs () at - line 6.
+The lexical_subs feature is experimental at - line 7.
+Prototype mismatch: sub phred () vs none at - line 8.
+Constant subroutine phred redefined at - line 8.
+The lexical_subs feature is experimental at - line 9.
+Prototype mismatch: sub jorge: none vs () at - line 10.
+########
+# op.c
+no warnings 'redefine' ;
+sub fred () { 1 }
+sub fred () { 2 }
+EXPECT
 ########
 # op.c
 no warnings 'redefine' ;
 sub fred () { 1 }
 *fred = sub () { 2 };
 EXPECT
-Constant subroutine main::fred redefined at - line 4.
 ########
 # op.c
 use warnings 'redefine' ;
@@ -791,70 +846,65 @@ EXPECT
 Format FRED redefined at - line 5.
 ########
 # op.c
-use warnings 'deprecated' ;
 push FRED;
 no warnings 'deprecated' ;
 push FRED;
 EXPECT
-Array @FRED missing the @ in argument 1 of push() at - line 3.
+Array @FRED missing the @ in argument 1 of push() at - line 2.
 ########
 # op.c
-use warnings 'deprecated' ;
 @a = keys FRED ;
 no warnings 'deprecated' ;
 @a = keys FRED ;
 EXPECT
-Hash %FRED missing the % in argument 1 of keys() at - line 3.
+Hash %FRED missing the % in argument 1 of keys() at - line 2.
 ########
 # op.c
-BEGIN {
-    if ($^O eq 'MacOS') {
-       print <<EOM;
-SKIPPED
-# no exec on Mac OS
-EOM
-       exit;
-    }
-}
-use warnings 'syntax' ;
+use warnings 'exec' ;
 exec "$^X -e 1" ; 
 my $a
 EXPECT
-Statement unlikely to be reached at - line 13.
+Statement unlikely to be reached at - line 4.
        (Maybe you meant system() when you said exec()?)
 ########
+# op.c, no warning if exec isn't a statement.
+use warnings 'exec' ;
+$a || exec "$^X -e 1" ;
+my $a
+EXPECT
+########
+# op.c
+defined(@a);
+EXPECT
+defined(@array) is deprecated at - line 2.
+       (Maybe you should just omit the defined()?)
+########
 # op.c
-use warnings 'deprecated' ;
 my @a; defined(@a);
 EXPECT
-defined(@array) is deprecated at - line 3.
+defined(@array) is deprecated at - line 2.
        (Maybe you should just omit the defined()?)
 ########
 # op.c
-use warnings 'deprecated' ;
 defined(@a = (1,2,3));
 EXPECT
-defined(@array) is deprecated at - line 3.
+defined(@array) is deprecated at - line 2.
+       (Maybe you should just omit the defined()?)
+########
+# op.c
+defined(%h);
+EXPECT
+defined(%hash) is deprecated at - line 2.
        (Maybe you should just omit the defined()?)
 ########
 # op.c
-use warnings 'deprecated' ;
 my %h; defined(%h);
 EXPECT
-defined(%hash) is deprecated at - line 3.
+defined(%hash) is deprecated at - line 2.
        (Maybe you should just omit the defined()?)
 ########
 # op.c
-BEGIN {
-    if ($^O eq 'MacOS') {
-       print <<EOM;
-SKIPPED
-# no exec on Mac OS
-EOM
-       exit;
-    }
-}
-no warnings 'syntax' ;
+no warnings 'exec' ;
 exec "$^X -e 1" ; 
 my $a
 EXPECT
@@ -863,8 +913,83 @@ EXPECT
 # op.c
 sub fred();
 sub fred($) {}
+use constant foo=>bar; sub foo(@);
+use constant bav=>bar; sub bav(); # no warning
+sub btu; sub btu();
 EXPECT
 Prototype mismatch: sub main::fred () vs ($) at - line 3.
+Prototype mismatch: sub foo () vs (@) at - line 4.
+Prototype mismatch: sub btu: none vs () at - line 6.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+sub frèd();
+sub frèd($) {}
+EXPECT
+Prototype mismatch: sub main::frèd () vs ($) at - line 5.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+eval "sub fòò (@\$\0) {}";
+EXPECT
+Prototype after '@' for main::fòò : @$\0 at (eval 1) line 1.
+Illegal character in prototype for main::fòò : @$\0 at (eval 1) line 1.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+eval "sub foo (@\0) {}";
+EXPECT
+Prototype after '@' for main::foo : @\0 at (eval 1) line 1.
+Illegal character in prototype for main::foo : @\0 at (eval 1) line 1.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+BEGIN { $::{"foo"} = "\@\$\0L\351on" }
+BEGIN { eval "sub foo (@\$\0L\x{c3}\x{a9}on) {}"; }
+EXPECT
+Prototype after '@' for main::foo : @$\x{0}L... at (eval 1) line 1.
+Illegal character in prototype for main::foo : @$\x{0}L... at (eval 1) line 1.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+BEGIN { eval "sub foo (@\0) {}"; }
+EXPECT
+Prototype after '@' for main::foo : @\0 at (eval 1) line 1.
+Illegal character in prototype for main::foo : @\0 at (eval 1) line 1.
+########
+# op.c
+use warnings;
+eval "sub foo (@\xAB) {}";
+EXPECT
+Prototype after '@' for main::foo : @\x{ab} at (eval 1) line 1.
+Illegal character in prototype for main::foo : @\x{ab} at (eval 1) line 1.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+BEGIN { eval "sub foo (@\x{30cb}) {}"; }
+EXPECT
+Prototype after '@' for main::foo : @\x{30cb} at (eval 1) line 1.
+Illegal character in prototype for main::foo : @\x{30cb} at (eval 1) line 1.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings;
+BEGIN { $::{"foo"} = "\x{30cb}" }
+BEGIN { eval "sub foo {}"; }
+EXPECT
+Prototype mismatch: sub main::foo (ニ) vs none at (eval 1) line 1.
 ########
 # op.c
 $^W = 0 ;
@@ -885,12 +1010,203 @@ Prototype mismatch: sub main::fred () vs ($) at - line 4.
 Prototype mismatch: sub main::freD () vs ($) at - line 11.
 Prototype mismatch: sub main::FRED () vs ($) at - line 14.
 ########
+# op.c [S_simplify_sort]
+# [perl #86136]
+my @tests = split /^/, '
+  sort {$a <=> $b} @a;
+  sort {$a cmp $b} @a;
+  { use integer; sort {$a <=> $b} @a}
+  sort {$b <=> $a} @a;
+  sort {$b cmp $a} @a;
+  { use integer; sort {$b <=> $a} @a}
+';
+for my $pragma ('use warnings "syntax";', '') {
+  for my $vars ('', 'my $a;', 'my $b;', 'my ($a,$b);') {
+    for my $inner_stmt ('', 'print;', 'func();') {
+      eval "#line " . ++$line . "01 -\n$pragma\n$vars"
+          . join "", map s/sort \{\K/$inner_stmt/r, @tests;
+      $@ and die;
+    }
+  }
+}
+sub func{}
+use warnings 'syntax';
+my $a;
+# These used to be errors!
+sort { ; } $a <=> $b;
+sort { ; } $a, "<=>";
+sort { ; } $a, $cmp;
+sort $a, $b if $cmpany_name;
+sort if $a + $cmp;
+sort @t; $a + $cmp;
+EXPECT
+"my $a" used in sort comparison at - line 403.
+"my $a" used in sort comparison at - line 404.
+"my $a" used in sort comparison at - line 405.
+"my $a" used in sort comparison at - line 406.
+"my $a" used in sort comparison at - line 407.
+"my $a" used in sort comparison at - line 408.
+"my $a" used in sort comparison at - line 503.
+"my $a" used in sort comparison at - line 504.
+"my $a" used in sort comparison at - line 505.
+"my $a" used in sort comparison at - line 506.
+"my $a" used in sort comparison at - line 507.
+"my $a" used in sort comparison at - line 508.
+"my $a" used in sort comparison at - line 603.
+"my $a" used in sort comparison at - line 604.
+"my $a" used in sort comparison at - line 605.
+"my $a" used in sort comparison at - line 606.
+"my $a" used in sort comparison at - line 607.
+"my $a" used in sort comparison at - line 608.
+"my $b" used in sort comparison at - line 703.
+"my $b" used in sort comparison at - line 704.
+"my $b" used in sort comparison at - line 705.
+"my $b" used in sort comparison at - line 706.
+"my $b" used in sort comparison at - line 707.
+"my $b" used in sort comparison at - line 708.
+"my $b" used in sort comparison at - line 803.
+"my $b" used in sort comparison at - line 804.
+"my $b" used in sort comparison at - line 805.
+"my $b" used in sort comparison at - line 806.
+"my $b" used in sort comparison at - line 807.
+"my $b" used in sort comparison at - line 808.
+"my $b" used in sort comparison at - line 903.
+"my $b" used in sort comparison at - line 904.
+"my $b" used in sort comparison at - line 905.
+"my $b" used in sort comparison at - line 906.
+"my $b" used in sort comparison at - line 907.
+"my $b" used in sort comparison at - line 908.
+"my $a" used in sort comparison at - line 1003.
+"my $b" used in sort comparison at - line 1003.
+"my $a" used in sort comparison at - line 1004.
+"my $b" used in sort comparison at - line 1004.
+"my $a" used in sort comparison at - line 1005.
+"my $b" used in sort comparison at - line 1005.
+"my $b" used in sort comparison at - line 1006.
+"my $a" used in sort comparison at - line 1006.
+"my $b" used in sort comparison at - line 1007.
+"my $a" used in sort comparison at - line 1007.
+"my $b" used in sort comparison at - line 1008.
+"my $a" used in sort comparison at - line 1008.
+"my $a" used in sort comparison at - line 1103.
+"my $b" used in sort comparison at - line 1103.
+"my $a" used in sort comparison at - line 1104.
+"my $b" used in sort comparison at - line 1104.
+"my $a" used in sort comparison at - line 1105.
+"my $b" used in sort comparison at - line 1105.
+"my $b" used in sort comparison at - line 1106.
+"my $a" used in sort comparison at - line 1106.
+"my $b" used in sort comparison at - line 1107.
+"my $a" used in sort comparison at - line 1107.
+"my $b" used in sort comparison at - line 1108.
+"my $a" used in sort comparison at - line 1108.
+"my $a" used in sort comparison at - line 1203.
+"my $b" used in sort comparison at - line 1203.
+"my $a" used in sort comparison at - line 1204.
+"my $b" used in sort comparison at - line 1204.
+"my $a" used in sort comparison at - line 1205.
+"my $b" used in sort comparison at - line 1205.
+"my $b" used in sort comparison at - line 1206.
+"my $a" used in sort comparison at - line 1206.
+"my $b" used in sort comparison at - line 1207.
+"my $a" used in sort comparison at - line 1207.
+"my $b" used in sort comparison at - line 1208.
+"my $a" used in sort comparison at - line 1208.
+########
+# op.c [S_simplify_sort]
+use warnings 'syntax'; use 5.01;
+state $a;
+sort { $a <=> $b } ();
+EXPECT
+"state $a" used in sort comparison at - line 4.
+########
+# op.c [Perl_ck_cmp]
+use warnings 'syntax' ;
+no warnings 'deprecated';
+@a = $[ < 5;
+@a = $[ > 5;
+@a = $[ <= 5;
+@a = $[ >= 5;
+@a = 42 < $[;
+@a = 42 > $[;
+@a = 42 <= $[;
+@a = 42 >= $[;
+use integer;
+@a = $[ < 5;
+@a = $[ > 5;
+@a = $[ <= 5;
+@a = $[ >= 5;
+@a = 42 < $[;
+@a = 42 > $[;
+@a = 42 <= $[;
+@a = 42 >= $[;
+no integer;
+@a = $[ < $5;
+@a = $[ > $5;
+@a = $[ <= $5;
+@a = $[ >= $5;
+@a = $42 < $[;
+@a = $42 > $[;
+@a = $42 <= $[;
+@a = $42 >= $[;
+use integer;
+@a = $[ < $5;
+@a = $[ > $5;
+@a = $[ <= $5;
+@a = $[ >= $5;
+@a = $42 < $[;
+@a = $42 > $[;
+@a = $42 <= $[;
+@a = $42 >= $[;
+EXPECT
+$[ used in numeric lt (<) (did you mean $] ?) at - line 4.
+$[ used in numeric gt (>) (did you mean $] ?) at - line 5.
+$[ used in numeric le (<=) (did you mean $] ?) at - line 6.
+$[ used in numeric ge (>=) (did you mean $] ?) at - line 7.
+$[ used in numeric lt (<) (did you mean $] ?) at - line 8.
+$[ used in numeric gt (>) (did you mean $] ?) at - line 9.
+$[ used in numeric le (<=) (did you mean $] ?) at - line 10.
+$[ used in numeric ge (>=) (did you mean $] ?) at - line 11.
+$[ used in numeric lt (<) (did you mean $] ?) at - line 13.
+$[ used in numeric gt (>) (did you mean $] ?) at - line 14.
+$[ used in numeric le (<=) (did you mean $] ?) at - line 15.
+$[ used in numeric ge (>=) (did you mean $] ?) at - line 16.
+$[ used in numeric lt (<) (did you mean $] ?) at - line 17.
+$[ used in numeric gt (>) (did you mean $] ?) at - line 18.
+$[ used in numeric le (<=) (did you mean $] ?) at - line 19.
+$[ used in numeric ge (>=) (did you mean $] ?) at - line 20.
+########
+# op.c [Perl_ck_length]
+use warnings 'syntax' ;
+length(@a);
+length(%b);
+length(@$c);
+length(%$d);
+length($a);
+length(my %h);
+length(my @g);
+EXPECT
+length() used on @a (did you mean "scalar(@a)"?) at - line 3.
+length() used on %b (did you mean "scalar(keys %b)"?) at - line 4.
+length() used on @array (did you mean "scalar(@array)"?) at - line 5.
+length() used on %hash (did you mean "scalar(keys %hash)"?) at - line 6.
+length() used on %h (did you mean "scalar(keys %h)"?) at - line 8.
+length() used on @g (did you mean "scalar(@g)"?) at - line 9.
+########
 # op.c
 use warnings 'syntax' ;
 join /---/, 'x', 'y', 'z';
 EXPECT
 /---/ should probably be written as "---" at - line 3.
 ########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+use warnings 'syntax' ;
+join /~~~/, 'x', 'y', 'z';
+EXPECT
+/~~~/ should probably be written as "~~~" at - line 5.
+########
 # op.c [Perl_peep]
 use warnings 'prototype' ;
 fred() ; 
@@ -982,6 +1298,7 @@ $a = $b < $c & $d;
 $a = $b >= $c ^ $d;
 $a = $b <= $c | $d;
 $a = $b <=> $c & $d;
+$a &= $b == $c; $a |= $b == $c; $a ^= $b == $c; # shouldn't warn
 no warnings 'precedence';
 $a = $b & $c == $d;
 $a = $b ^ $c != $d;
@@ -1025,3 +1342,236 @@ Possible precedence problem on bitwise & operator at - line 7.
 Possible precedence problem on bitwise ^ operator at - line 8.
 Possible precedence problem on bitwise | operator at - line 9.
 Possible precedence problem on bitwise & operator at - line 10.
+########
+# op.c
+
+# ok   => local() has desired effect;
+# ignore=> local() silently ignored
+
+use warnings 'syntax';
+
+local(undef);          # OP_UNDEF              ignore
+sub lval : lvalue {};
+local(lval());         # OP_ENTERSUB
+local($x **= 1);       # OP_POW
+local($x *=  1);       # OP_MULTIPLY
+local($x /=  1);       # OP_DIVIDE
+local($x %=  1);       # OP_MODULO
+local($x x=  1);       # OP_REPEAT
+local($x +=  1);       # OP_ADD
+local($x -=  1);       # OP_SUBTRACT
+local($x .=  1);       # OP_CONCAT
+local($x <<= 1);       # OP_LEFT_SHIFT
+local($x >>= 1);       # OP_RIGHT_SHIFT
+local($x &=  1);       # OP_BIT_AND
+local($x ^=  1);       # OP_BIT_XOR
+local($x |=  1);       # OP_BIT_OR
+{
+    use integer;
+    local($x *= 1);    # OP_I_MULTIPLY
+    local($x /= 1);    # OP_I_DIVIDE
+    local($x %= 1);    # OP_I_MODULO
+    local($x += 1);    # OP_I_ADD
+    local($x -= 1);    # OP_I_SUBTRACT
+}
+local($x?$y:$z) = 1;   # OP_COND_EXPR          ok
+# these two are fatal run-time errors instead
+#local(@$a);           # OP_RV2AV              ok
+#local(%$a);           # OP_RV2HV              ok
+local(*a);             # OP_RV2GV              ok
+local(@a[1,2]);                # OP_ASLICE             ok
+local(@a{1,2});                # OP_HSLICE             ok
+local(@a = (1,2));     # OP_AASSIGN
+local($$x);            # OP_RV2SV              ok
+local($#a);            # OP_AV2ARYLEN
+local($x =   1);       # OP_SASSIGN
+local($x &&= 1);       # OP_ANDASSIGN
+local($x ||= 1);       # OP_ORASSIGN
+local($x //= 1);       # OP_DORASSIGN
+local($a[0]);          # OP_AELEMFAST          ok
+
+local(substr($x,0,1)); # OP_SUBSTR
+local(pos($x));                # OP_POS
+local(vec($x,0,1));    # OP_VEC
+local($a[$b]);         # OP_AELEM              ok
+local($a{$b});         # OP_HELEM              ok
+
+no warnings 'syntax';
+EXPECT
+Useless localization of subroutine entry at - line 10.
+Useless localization of exponentiation (**) at - line 11.
+Useless localization of multiplication (*) at - line 12.
+Useless localization of division (/) at - line 13.
+Useless localization of modulus (%) at - line 14.
+Useless localization of repeat (x) at - line 15.
+Useless localization of addition (+) at - line 16.
+Useless localization of subtraction (-) at - line 17.
+Useless localization of concatenation (.) or string at - line 18.
+Useless localization of left bitshift (<<) at - line 19.
+Useless localization of right bitshift (>>) at - line 20.
+Useless localization of bitwise and (&) at - line 21.
+Useless localization of bitwise xor (^) at - line 22.
+Useless localization of bitwise or (|) at - line 23.
+Useless localization of integer multiplication (*) at - line 26.
+Useless localization of integer division (/) at - line 27.
+Useless localization of integer modulus (%) at - line 28.
+Useless localization of integer addition (+) at - line 29.
+Useless localization of integer subtraction (-) at - line 30.
+Useless localization of list assignment at - line 39.
+Useless localization of array length at - line 41.
+Useless localization of scalar assignment at - line 42.
+Useless localization of logical and assignment (&&=) at - line 43.
+Useless localization of logical or assignment (||=) at - line 44.
+Useless localization of defined or assignment (//=) at - line 45.
+Useless localization of substr at - line 48.
+Useless localization of match position at - line 49.
+Useless localization of vec at - line 50.
+########
+# op.c
+my $x1 if 0;
+my @x2 if 0;
+my %x3 if 0;
+my ($x4) if 0;
+my ($x5,@x6, %x7) if 0;
+0 && my $z1;
+0 && my (%z2);
+# these shouldn't warn
+our $x if 0;
+our $x unless 0;
+if (0) { my $w1 }
+if (my $w2) { $a=1 }
+if ($a && (my $w3 = 1)) {$a = 2}
+
+EXPECT
+Deprecated use of my() in false conditional at - line 2.
+Deprecated use of my() in false conditional at - line 3.
+Deprecated use of my() in false conditional at - line 4.
+Deprecated use of my() in false conditional at - line 5.
+Deprecated use of my() in false conditional at - line 6.
+Deprecated use of my() in false conditional at - line 7.
+Deprecated use of my() in false conditional at - line 8.
+########
+# op.c
+$[ = 1;
+($[) = 1;
+use warnings 'deprecated';
+$[ = 2;
+($[) = 2;
+no warnings 'deprecated';
+$[ = 3;
+($[) = 3;
+EXPECT
+Use of assignment to $[ is deprecated at - line 2.
+Use of assignment to $[ is deprecated at - line 3.
+Use of assignment to $[ is deprecated at - line 5.
+Use of assignment to $[ is deprecated at - line 6.
+########
+# op.c
+use warnings 'void';
+@x = split /y/, "z";
+$x = split /y/, "z";
+     split /y/, "z";
+no warnings 'void';
+@x = split /y/, "z";
+$x = split /y/, "z";
+     split /y/, "z";
+EXPECT
+Useless use of split in void context at - line 5.
+########
+# op.c
+use warnings 'redefine' ;
+use utf8;
+use open qw( :utf8 :std );
+sub frèd {}
+sub frèd {}
+no warnings 'redefine' ;
+sub frèd {}
+EXPECT
+Subroutine frèd redefined at - line 6.
+########
+# op.c
+use warnings 'redefine' ;
+use utf8;
+use open qw( :utf8 :std );
+sub frèd () { 1 }
+sub frèd () { 1 }
+no warnings 'redefine' ;
+sub frèd () { 1 }
+EXPECT
+Constant subroutine frèd redefined at - line 6.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+sub frèd () { 1 }
+sub frèd () { 2 }
+EXPECT
+Constant subroutine frèd redefined at - line 5.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+sub frèd () { 1 }
+*frèd = sub () { 2 };
+EXPECT
+Constant subroutine main::frèd redefined at - line 5.
+########
+# op.c
+use warnings 'redefine' ;
+use utf8;
+use open qw( :utf8 :std );
+sub ᚠርƊ {}
+sub ᚠርƊ {}
+no warnings 'redefine' ;
+sub ᚠርƊ {}
+EXPECT
+Subroutine ᚠርƊ redefined at - line 6.
+########
+# op.c
+use warnings 'redefine' ;
+use utf8;
+use open qw( :utf8 :std );
+sub ᚠርƊ () { 1 }
+sub ᚠርƊ () { 1 }
+no warnings 'redefine' ;
+sub ᚠርƊ () { 1 }
+EXPECT
+Constant subroutine ᚠርƊ redefined at - line 6.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+sub ᚠርƊ () { 1 }
+sub ᚠርƊ () { 2 }
+EXPECT
+Constant subroutine ᚠርƊ redefined at - line 5.
+########
+# op.c
+use utf8;
+use open qw( :utf8 :std );
+sub ᚠርƊ () { 1 }
+*ᚠርƊ = sub () { 2 };
+EXPECT
+Constant subroutine main::ᚠርƊ redefined at - line 5.
+########
+# OPTION regex
+sub DynaLoader::dl_error {};
+use warnings;
+# We're testing that the warnings report the same line number:
+eval <<'EOC' or die $@;
+{
+    DynaLoader::boot_DynaLoader("DynaLoader");
+}
+EOC
+eval <<'EOC' or die $@;
+BEGIN {
+    DynaLoader::boot_DynaLoader("DynaLoader");
+}
+1
+EOC
+EXPECT
+OPTION regex
+\ASubroutine DynaLoader::dl_error redefined at \(eval 1\) line 2\.
+?(?s).*
+Subroutine DynaLoader::dl_error redefined at \(eval 2\) line 2\.
+########