This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #132527] Allow 4-arg substr(delete ...)
authorFather Chrysostomos <sprout@cpan.org>
Sat, 2 Dec 2017 02:47:58 +0000 (18:47 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 2 Dec 2017 02:47:58 +0000 (18:47 -0800)
Commit 19a8de4862 broke 4-arg substr with ‘delete’ (and various other
ops) for its first argument.  Since historically these have been
allowed, use a ‘loose’ lvalue context such as entersub when lvaluify-
ing the first argument.

op.c
t/op/substr.t

diff --git a/op.c b/op.c
index 7e7727a..7030af0 100644 (file)
--- a/op.c
+++ b/op.c
@@ -13388,7 +13388,10 @@ Perl_ck_substr(pTHX_ OP *o)
        if (kid->op_type == OP_NULL)
            kid = OpSIBLING(kid);
        if (kid)
-           op_lvalue(kid, o->op_type);
+           /* Historically, substr(delete $foo{bar},...) has been allowed
+              with 4-arg substr.  Keep it working by applying entersub
+              lvalue context.  */
+           op_lvalue(kid, OP_ENTERSUB);
 
     }
     return o;
index dade46d..9becaf7 100644 (file)
@@ -22,7 +22,7 @@ $SIG{__WARN__} = sub {
      }
 };
 
-plan(399);
+plan(400);
 
 run_tests() unless caller;
 
@@ -909,4 +909,13 @@ fresh_perl_is('$0 = "/usr/bin/perl"; substr($0, 0, 0, $0)', '', {}, "(perl #1293
     is $#ta, 23;
 }
 
+{ # [perl #132527]
+    use feature 'refaliasing';
+    no warnings 'experimental::refaliasing';
+    my $h;
+    \$h{foo} = \(my $bar = "baz");
+    substr delete $h{foo}, 1, 1, o=>;
+    is $bar, boz => 'first arg to 4-arg substr is loose lvalue context';
+}
+
 1;