In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/05f7c1e8a76f2b5ef9d680a366d3be0f964c2102?hp=82f82fdb58cb3bf9651ec1ba6904780eb1105021>

- Log -----------------------------------------------------------------
commit 05f7c1e8a76f2b5ef9d680a366d3be0f964c2102
Merge: 82f82fd 82848c1
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Sat Oct 11 10:24:33 2014 -0700

    [Merge] Lvalue references
    
    Also:
    • Single refgen optimisation now applies to \@ \% \& as well.
    • split-to-array no longer runs the risk of clobbering its argument
      and returning junk.
    • The split-to-array optimisation happens more often than before.
    • foreach my $x is no longer subject to the list-assignment-after-ali-
      asing bug (#89646).
-----------------------------------------------------------------------

Summary of changes:
 MANIFEST               |    1 +
 cop.h                  |    5 +-
 cpan/B-Debug/t/debug.t |    6 +
 embed.fnc              |    5 +-
 embed.h                |    6 +-
 ext/B/t/concise-xs.t   |    4 +
 ext/Opcode/Opcode.pm   |    4 +-
 feature.h              |    6 +
 lib/B/Deparse.pm       |   70 ++-
 lib/B/Deparse.t        |  266 +++++++-
 lib/B/Op_private.pm    |   34 +-
 lib/feature.pm         |   28 +-
 lib/warnings.pm        |   37 +-
 mg.c                   |   57 ++
 mg.h                   |    1 +
 mg_names.c             |    1 +
 mg_raw.h               |   14 +-
 mg_vtable.h            |   17 +-
 op.c                   |  416 +++++++++++--
 opcode.h               |  366 ++++++-----
 opnames.h              |    6 +-
 perly.act              | 1209 ++++++++++++++++++------------------
 perly.h                |   64 +-
 perly.tab              | 1592 ++++++++++++++++++++++++------------------------
 perly.y                |   37 +-
 pod/perldiag.pod       |   38 ++
 pod/perlexperiment.pod |   12 +
 pod/perlguts.pod       |   14 +-
 pod/perlop.pod         |    6 +-
 pod/perlref.pod        |  103 ++++
 pod/perlsyn.pod        |   17 +-
 pp.c                   |  206 +++++++
 pp_ctl.c               |   12 +-
 pp_hot.c               |   36 +-
 pp_proto.h             |    4 +
 proto.h                |   30 +-
 regen/feature.pl       |   26 +-
 regen/mg_vtable.pl     |   39 +-
 regen/op_private       |   23 +-
 regen/opcode.pl        |    2 +-
 regen/opcodes          |    4 +
 regen/warnings.pl      |    4 +-
 scope.c                |    2 -
 sv.c                   |   10 +-
 t/lib/warnings/op      |    2 +-
 t/op/for.t             |    8 +-
 t/op/lvref.t           |  574 +++++++++++++++++
 t/op/ref.t             |    4 +-
 t/op/split.t           |    9 +-
 warnings.h             |    7 +-
 50 files changed, 3707 insertions(+), 1737 deletions(-)
 create mode 100644 t/op/lvref.t

diff --git a/MANIFEST b/MANIFEST
index 917f2f9..66ba5df 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -5138,6 +5138,7 @@ t/op/local.t                      See if local works
 t/op/lock.t                    Tests for lock args & retval (no threads)
 t/op/loopctl.t                 See if next/last/redo work
 t/op/lop.t                     See if logical operators work
+t/op/lvref.t                   See if lvalue references work
 t/op/magic-27839.t             Test for #27839, skipped for minitest
 t/op/magic.t                   See if magic variables work
 t/op/method.t                  See if method calls work
diff --git a/cop.h b/cop.h
index 37980f0..9c25555 100644
--- a/cop.h
+++ b/cop.h
@@ -761,7 +761,9 @@ struct block_loop {
        ((c)->blk_loop.itervar_u.oldcomppad                             \
         ? (CxPADLOOP(c)                                                \
            ? CxITERVAR_PADSV(c)                                        \
-           : &GvSV((c)->blk_loop.itervar_u.gv))                        \
+           : isGV((c)->blk_loop.itervar_u.gv)                          \
+               ? &GvSV((c)->blk_loop.itervar_u.gv)                     \
+               : (SV **)&(c)->blk_loop.itervar_u.gv)                   \
         : (SV**)NULL)
 
 #define CxLABEL(c)     (0 + CopLABEL((c)->blk_oldcop))
@@ -980,6 +982,7 @@ struct context {
 
 /* private flags for CXt_LOOP */
 #define CXp_FOR_DEF    0x10    /* foreach using $_ */
+#define CXp_FOR_LVREF  0x20    /* foreach using \$var */
 #define CxPADLOOP(c)   ((c)->blk_loop.my_op->op_targ)
 
 /* private flags for CXt_SUBST */
diff --git a/cpan/B-Debug/t/debug.t b/cpan/B-Debug/t/debug.t
index e523d3d..0af3bd9 100644
--- a/cpan/B-Debug/t/debug.t
+++ b/cpan/B-Debug/t/debug.t
@@ -59,6 +59,12 @@ leave enter nextstate label leaveloop enterloop null and 
defined null
 threadsv readline gv lineseq nextstate aassign null pushmark split pushre
 threadsv const null pushmark rvav gv nextstate subst const unstack
 EOF
+} elsif ($] >= 5.021005) {
+  $b=<<EOF;
+leave enter nextstate label leaveloop enterloop null and defined null null
+gvsv readline gv lineseq nextstate split pushre null
+gvsv const nextstate subst const unstack
+EOF
 } else {
   $b=<<EOF;
 leave enter nextstate label leaveloop enterloop null and defined null null
diff --git a/embed.fnc b/embed.fnc
index a0cac62..bceca6b 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -554,6 +554,7 @@ Ap  |void   |gv_name_set    |NN GV* gv|NN const char 
*name|U32 len|U32 flags
 px     |GV *   |gv_override    |NN const char * const name \
                                |const STRLEN len
 XMpd   |void   |gv_try_downgrade|NN GV* gv
+p      |void   |gv_setref      |NN SV *const dstr|NN SV *const sstr
 Apd    |HV*    |gv_stashpv     |NN const char* name|I32 flags
 Apd    |HV*    |gv_stashpvn    |NN const char* name|U32 namelen|I32 flags
 #if defined(PERL_IN_GV_C)
@@ -865,6 +866,7 @@ p   |int    |magic_setdefelem|NN SV* sv|NN MAGIC* mg
 p      |int    |magic_setenv   |NN SV* sv|NN MAGIC* mg
 dp     |int    |magic_sethint  |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_setisa   |NN SV* sv|NN MAGIC* mg
+p      |int    |magic_setlvref |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_setmglob |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_setnkeys |NN SV* sv|NN MAGIC* mg
 p      |int    |magic_setpack  |NN SV* sv|NN MAGIC* mg
@@ -1925,7 +1927,7 @@ s |void   |fixup_errno_string|NN SV* sv
 
 #if defined(PERL_IN_OP_C)
 sRn    |bool   |is_handle_constructor|NN const OP *o|I32 numargs
-sR     |I32    |is_list_assignment|NULLOK const OP *o
+sR     |I32    |assignment_type|NULLOK const OP *o
 s      |void   |forget_pmop    |NN PMOP *const o
 s      |void   |find_and_forget_pmops  |NN OP *o
 s      |void   |cop_free       |NN COP *cop
@@ -2350,7 +2352,6 @@ s |SV *   |more_sv
 s      |bool   |sv_2iuv_common |NN SV *const sv
 s      |void   |glob_assign_glob|NN SV *const dstr|NN SV *const sstr \
                |const int dtype
-s      |void   |glob_assign_ref|NN SV *const dstr|NN SV *const sstr
 sRn    |PTR_TBL_ENT_t *|ptr_table_find|NN PTR_TBL_t *const tbl|NULLOK const 
void *const sv
 s      |void   |anonymise_cv_maybe     |NN GV *gv|NN CV *cv
 #endif
diff --git a/embed.h b/embed.h
index d73816f..b4176c7 100644
--- a/embed.h
+++ b/embed.h
@@ -1108,6 +1108,7 @@
 #define ck_null(a)             Perl_ck_null(aTHX_ a)
 #define ck_open(a)             Perl_ck_open(aTHX_ a)
 #define ck_readline(a)         Perl_ck_readline(aTHX_ a)
+#define ck_refassign(a)                Perl_ck_refassign(aTHX_ a)
 #define ck_repeat(a)           Perl_ck_repeat(aTHX_ a)
 #define ck_require(a)          Perl_ck_require(aTHX_ a)
 #define ck_return(a)           Perl_ck_return(aTHX_ a)
@@ -1173,6 +1174,7 @@
 #define get_no_modify()                Perl_get_no_modify(aTHX)
 #define get_opargs()           Perl_get_opargs(aTHX)
 #define gv_override(a,b)       Perl_gv_override(aTHX_ a,b)
+#define gv_setref(a,b)         Perl_gv_setref(aTHX_ a,b)
 #define gv_try_downgrade(a)    Perl_gv_try_downgrade(aTHX_ a)
 #define hv_ename_add(a,b,c,d)  Perl_hv_ename_add(aTHX_ a,b,c,d)
 #define hv_ename_delete(a,b,c,d)       Perl_hv_ename_delete(aTHX_ a,b,c,d)
@@ -1225,6 +1227,7 @@
 #define magic_setenv(a,b)      Perl_magic_setenv(aTHX_ a,b)
 #define magic_sethint(a,b)     Perl_magic_sethint(aTHX_ a,b)
 #define magic_setisa(a,b)      Perl_magic_setisa(aTHX_ a,b)
+#define magic_setlvref(a,b)    Perl_magic_setlvref(aTHX_ a,b)
 #define magic_setmglob(a,b)    Perl_magic_setmglob(aTHX_ a,b)
 #define magic_setnkeys(a,b)    Perl_magic_setnkeys(aTHX_ a,b)
 #define magic_setpack(a,b)     Perl_magic_setpack(aTHX_ a,b)
@@ -1508,6 +1511,7 @@
 #define aassign_common_vars(a) S_aassign_common_vars(aTHX_ a)
 #define apply_attrs(a,b,c)     S_apply_attrs(aTHX_ a,b,c)
 #define apply_attrs_my(a,b,c,d)        S_apply_attrs_my(aTHX_ a,b,c,d)
+#define assignment_type(a)     S_assignment_type(aTHX_ a)
 #define bad_type_gv(a,b,c,d,e) S_bad_type_gv(aTHX_ a,b,c,d,e)
 #define bad_type_pv(a,b,c,d,e) S_bad_type_pv(aTHX_ a,b,c,d,e)
 #define clear_special_blocks(a,b,c)    S_clear_special_blocks(aTHX_ a,b,c)
@@ -1521,7 +1525,6 @@
 #define gen_constant_list(a)   S_gen_constant_list(aTHX_ a)
 #define inplace_aassign(a)     S_inplace_aassign(aTHX_ a)
 #define is_handle_constructor  S_is_handle_constructor
-#define is_list_assignment(a)  S_is_list_assignment(aTHX_ a)
 #define listkids(a)            S_listkids(aTHX_ a)
 #define looks_like_bool(a)     S_looks_like_bool(aTHX_ a)
 #define modkids(a,b)           S_modkids(aTHX_ a,b)
@@ -1662,7 +1665,6 @@
 #define find_uninit_var(a,b,c) S_find_uninit_var(aTHX_ a,b,c)
 #define glob_2number(a)                S_glob_2number(aTHX_ a)
 #define glob_assign_glob(a,b,c)        S_glob_assign_glob(aTHX_ a,b,c)
-#define glob_assign_ref(a,b)   S_glob_assign_ref(aTHX_ a,b)
 #define more_sv()              S_more_sv(aTHX)
 #define not_a_number(a)                S_not_a_number(aTHX_ a)
 #define not_incrementable(a)   S_not_incrementable(aTHX_ a)
diff --git a/ext/B/t/concise-xs.t b/ext/B/t/concise-xs.t
index dce0a2e..865a164 100644
--- a/ext/B/t/concise-xs.t
+++ b/ext/B/t/concise-xs.t
@@ -158,6 +158,7 @@ my $testpkgs = {
 
        constant => [qw/ ASSIGN CVf_LVALUE
                     CVf_METHOD LIST_CONTEXT OP_CONST OP_LIST OP_RV2SV
+                    OP_AELEM
                     OP_STRINGIFY OPf_KIDS OPf_MOD OPf_REF OPf_SPECIAL
                     OPf_PARENS
                     OPf_STACKED OPf_WANT OPf_WANT_LIST OPf_WANT_SCALAR
@@ -180,6 +181,9 @@ my $testpkgs = {
                     OPpEVAL_BYTES OPpSUBSTR_REPL_FIRST) : (),
                     $] >= 5.019 ? qw(OP_PUSHMARK OP_NULL) : (),
                    'CVf_LOCKED', # This ends up as a constant, pre or post 5.10
+                    $] >= 5.021005 ? qw(OPpLVREF_TYPE OPpLVREF_SV
+                                        OPpLVREF_AV OPpLVREF_HV
+                                        OPpLVREF_CV OPpLVREF_ELEM) : (),
                    ],
                 },
 
diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm
index 3da8d94..7256126 100644
--- a/ext/Opcode/Opcode.pm
+++ b/ext/Opcode/Opcode.pm
@@ -6,7 +6,7 @@ use strict;
 
 our($VERSION, @ISA, @EXPORT_OK);
 
-$VERSION = "1.28";
+$VERSION = "1.29";
 
 use Carp;
 use Exporter ();
@@ -402,7 +402,7 @@ These are a hotchpotch of opcodes still waiting to be 
considered
 
     once
 
-    rv2gv refgen srefgen ref
+    rv2gv refgen srefgen ref refassign lvref lvrefslice lvavref
 
     bless -- could be used to change ownership of objects
             (reblessing)
diff --git a/feature.h b/feature.h
index 698302c..c6c71e3 100644
--- a/feature.h
+++ b/feature.h
@@ -93,6 +93,12 @@
         FEATURE_IS_ENABLED("__SUB__")) \
     )
 
+#define FEATURE_LVREF_IS_ENABLED \
+    ( \
+       CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
+        FEATURE_IS_ENABLED("lvref") \
+    )
+
 #define FEATURE_LEXSUBS_IS_ENABLED \
     ( \
        CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index 8496611..07cf10f 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -36,7 +36,8 @@ BEGIN {
                RXf_PMf_CHARSET RXf_PMf_KEEPCOPY
                CVf_LOCKED OPpREVERSE_INPLACE OPpSUBSTR_REPL_FIRST
                PMf_NONDESTRUCT OPpCONST_ARYBASE OPpEVAL_BYTES
-               SVpad_STATE)) {
+               OPpLVREF_TYPE OPpLVREF_SV OPpLVREF_AV OPpLVREF_HV
+               OPpLVREF_CV OPpLVREF_ELEM SVpad_STATE)) {
        eval { import B $_ };
        no strict 'refs';
        *{$_} = sub () {0} unless *{$_}{CODE};
@@ -322,7 +323,7 @@ BEGIN {
 
 
 
-BEGIN { for (qw[ const stringify rv2sv list glob pushmark null]) {
+BEGIN { for (qw[ const stringify rv2sv list glob pushmark null aelem]) {
     eval "sub OP_\U$_ () { " . opnumber($_) . "}"
 }}
 
@@ -1216,7 +1217,8 @@ sub maybe_local {
     my $self = shift;
     my($op, $cx, $text) = @_;
     my $name = $op->name;
-    my $our_intro = ($name =~ /^(?:(?:gv|rv2)[ash]v|split)$/)
+    my $our_intro = ($name =~ /^(?:(?:gv|rv2)[ash]v|split|refassign
+                                 |lv(?:av)?ref)$/x)
                        ? OPpOUR_INTRO
                        : 0;
     my $lval_intro = $name eq 'split' ? 0 : OPpLVAL_INTRO;
@@ -2500,7 +2502,7 @@ BEGIN {
              'multiply=' => 7, 'i_multiply=' => 7,
              'divide=' => 7, 'i_divide=' => 7,
              'modulo=' => 7, 'i_modulo=' => 7,
-             'repeat=' => 7,
+             'repeat=' => 7, 'refassign' => 7, 'refassign=' => 7,
              'add=' => 7, 'i_add=' => 7,
              'subtract=' => 7, 'i_subtract=' => 7,
              'concat=' => 7,
@@ -3054,7 +3056,8 @@ sub pp_list {
        my $loppriv = $lop->private;
        if (!($loppriv & (OPpLVAL_INTRO|OPpOUR_INTRO)
                or $lopname eq "undef")
-           or $lopname =~ /^(?:entersub|exit|open|split)\z/)
+           or $lopname =~ /^(?:entersub|exit|open|split
+                              |lv(?:av)?ref(?:slice)?)\z/x)
        {
            $local = ""; # or not
            last;
@@ -3233,6 +3236,8 @@ sub loop_common {
            }
        } elsif ($var->name eq "gv") {
            $var = "\$" . $self->deparse($var, 1);
+       } else {
+           $var = $self->deparse($var, 1);
        }
        $body = $kid->first->first->sibling; # skip OP_AND and OP_ITER
        if (!is_state $body->first and $body->first->name !~ 
/^(?:stub|leave|scope)$/) {
@@ -5104,6 +5109,61 @@ sub pp_padcv {
     return $self->padany($op);
 }
 
+my %lvref_funnies = (
+    OPpLVREF_SV, => '$',
+    OPpLVREF_AV, => '@',
+    OPpLVREF_HV, => '%',
+    OPpLVREF_CV, => '&',
+);
+
+sub pp_refassign {
+    my ($self, $op, $cx) = @_;
+    my $left;
+    if ($op->private & OPpLVREF_ELEM) {
+       $left = $op->first ->sibling   ->first  ->first;
+                  #  rhs  ex-srefgen  ex-list  ex-[ah]elem
+       $left = maybe_local(@_, elem($self, $left, undef,
+                                    $left->targ == OP_AELEM
+                                       ? qw([ ] padav)
+                                       : qw({ } padhv)));
+    } elsif ($op->flags & OPf_STACKED) {
+       $left = maybe_local(@_,
+                           $lvref_funnies{$op->private & OPpLVREF_TYPE}
+                         . $self->deparse($op->first->sibling));
+    } else {
+       $left = &pp_padsv;
+    }
+    my $right = $self->deparse_binop_right($op, $op->first, 7);
+    return $self->maybe_parens("\\$left = $right", $cx, 7);
+}
+
+sub pp_lvref {
+    my ($self, $op, $cx) = @_;
+    my $code;
+    if ($op->private & OPpLVREF_ELEM) {
+       $code = $op->first->name =~ /av\z/ ? &pp_aelem : &pp_helem;
+    } elsif ($op->flags & OPf_STACKED) {
+       $code = maybe_local(@_,
+                           $lvref_funnies{$op->private & OPpLVREF_TYPE}
+                         . $self->deparse($op->first));
+    } else {
+       $code = &pp_padsv;
+    }
+    "\\$code";
+}
+
+sub pp_lvrefslice {
+    my ($self, $op, $cx) = @_;
+    '\\' . ($op->last->name =~ /av\z/ ? &pp_aslice : &pp_hslice);
+}
+
+sub pp_lvavref {
+    my ($self, $op, $cx) = @_;
+    '\\(' . ($op->flags & OPf_STACKED
+               ? maybe_local(@_, rv2x(@_, "\@"))
+               : &pp_padsv)  . ')'
+}
+
 1;
 __END__
 
diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t
index 16b0ad2..21e6cdc 100644
--- a/lib/B/Deparse.t
+++ b/lib/B/Deparse.t
@@ -92,6 +92,19 @@ EOC
     }
 }
 
+# Reset the ambient pragmas
+{
+    my ($b, $w, $h);
+    BEGIN {
+        ($b, $w, $h) = ($^H, ${^WARNING_BITS}, \%^H);
+    }
+    $deparse->ambient_pragmas (
+        hint_bits    => $b,
+        warning_bits => $w,
+        '%^H'        => $h,
+    );
+}
+
 use constant 'c', 'stuff';
 is((eval "sub ".$deparse->coderef2text(\&c))->(), 'stuff',
    'the subroutine generated by use constant deparses');
@@ -114,7 +127,7 @@ $a =~ s/.*possible typo.*\n//;         # Remove warning line
 $a =~ s/.*-i used with no filenames.*\n//;     # Remove warning line
 $a =~ s{\\340\\242}{\\s} if (ord("\\") == 224); # EBCDIC, cp 1047 or 037
 $a =~ s{\\274\\242}{\\s} if (ord("\\") == 188); # $^O eq 'posix-bc'
-$b = <<'EOF';
+$b = quotemeta <<'EOF';
 BEGIN { $^I = ".bak"; }
 BEGIN { $^W = 1; }
 BEGIN { $/ = "\n"; $\ = "\n"; }
@@ -124,7 +137,8 @@ LINE: while (defined($_ = <ARGV>)) {
     '???';
 }
 EOF
-is($a, $b,
+$b =~ s/our\\\(\\\@F\\\)/our[( ]\@F\\)?/; # accept both our @F and our(@F)
+like($a, qr/$b/,
    'command line flags deparse as BEGIN blocks setting control variables');
 
 $a = `$^X $path "-MO=Deparse" -e "use constant PI => 4" 2>&1`;
@@ -1602,3 +1616,251 @@ main::pop();
 state();
 use feature 'state';
 main::state();
+####
+# lvalue references
+# CONTEXT use feature "state", 'lvalue_refs', 'lexical_subs'; no warnings 
'experimental';
+our $x;
+\$x = \$x;
+my $m;
+\$m = \$x;
+\my $n = \$x;
+(\$x) = @_;
+\($x) = @_;
+\($m) = @_;
+(\$m) = @_;
+\my($p) = @_;
+(\my $r) = @_;
+\($x, my $a) = @{[\$x, \$x]};
+(\$x, \my $b) = @{[\$x, \$x]};
+\local $x = \3;
+\local($x) = \3;
+\state $c = \3;
+\state($d) = \3;
+\our $e = \3;
+\our($f) = \3;
+\$_[0] = foo();
+\($_[1]) = foo();
+my @a;
+\$a[0] = foo();
+\($a[1]) = foo();
+\local($a[1]) = foo();
+\@a[0,1] = foo();
+\(@a[2,3]) = foo();
+\local @a[0,1] = (\$a)x2;
+\$_{a} = foo();
+\($_{b}) = foo();
+my %h;
+\$h{a} = foo();
+\($h{b}) = foo();
+\local $h{a} = \$x;
+\local($h{b}) = \$x;
+\@h{'a','b'} = foo();
+\(@h{2,3}) = foo();
+\local @h{'a','b'} = (\$x)x2;
+\@_ = foo();
+\@a = foo();
+(\@_) = foo();
+(\@a) = foo();
+\my @c = foo();
+(\my @d) = foo();
+\(@_) = foo();
+\(@a) = foo();
+\my(@g) = foo();
+\local @_ = \@_;
+(\local @_) = \@_;
+\state @e = [1..3];
+\state(@f) = \3;
+\our @i = [1..3];
+\our(@h) = \3;
+\%_ = foo();
+\%h = foo();
+(\%_) = foo();
+(\%h) = foo();
+\my %c = foo();
+(\my %d) = foo();
+\local %_ = \%h;
+(\local %_) = \%h;
+\state %y = {1,2};
+\our %z = {1,2};
+(\our %zz) = {1,2};
+\&a = foo();
+(\&a) = foo();
+\(&a) = foo();
+{
+  my sub a;
+  \&a = foo();
+  (\&a) = foo();
+  \(&a) = foo();
+}
+(\$_, $_) = \(1, 2);
+$_ == 3 ? \$_ : $_ = \3;
+$_ == 3 ? \$_ : \$x = \3;
+\($_ == 3 ? $_ : $x) = \3;
+for \my $topic (\$1, \$2) {
+    die;
+}
+for \state $topic (\$1, \$2) {
+    die;
+}
+for \our $topic (\$1, \$2) {
+    die;
+}
+for \$_ (\$1, \$2) {
+    die;
+}
+for \my @a ([1,2], [3,4]) {
+    die;
+}
+for \state @a ([1,2], [3,4]) {
+    die;
+}
+for \our @a ([1,2], [3,4]) {
+    die;
+}
+for \@_ ([1,2], [3,4]) {
+    die;
+}
+for \my %a ({5,6}, {7,8}) {
+    die;
+}
+for \our %a ({5,6}, {7,8}) {
+    die;
+}
+for \state %a ({5,6}, {7,8}) {
+    die;
+}
+for \%_ ({5,6}, {7,8}) {
+    die;
+}
+{
+    my sub a;
+    for \&a (sub { 9; }, sub { 10; }) {
+        die;
+    }
+}
+for \&a (sub { 9; }, sub { 10; }) {
+    die;
+}
+>>>>
+our $x;
+\$x = \$x;
+my $m;
+\$m = \$x;
+\my $n = \$x;
+(\$x) = @_;
+(\$x) = @_;
+(\$m) = @_;
+(\$m) = @_;
+(\my $p) = @_;
+(\my $r) = @_;
+(\$x, \my $a) = @{[\$x, \$x];};
+(\$x, \my $b) = @{[\$x, \$x];};
+\local $x = \3;
+(\local $x) = \3;
+\state $c = \3;
+(\state $d) = \3;
+\our $e = \3;
+(\our $f) = \3;
+\$_[0] = foo();
+(\$_[1]) = foo();
+my @a;
+\$a[0] = foo();
+(\$a[1]) = foo();
+(\local $a[1]) = foo();
+(\@a[0, 1]) = foo();
+(\@a[2, 3]) = foo();
+(\local @a[0, 1]) = (\$a) x 2;
+\$_{'a'} = foo();
+(\$_{'b'}) = foo();
+my %h;
+\$h{'a'} = foo();
+(\$h{'b'}) = foo();
+\local $h{'a'} = \$x;
+(\local $h{'b'}) = \$x;
+(\@h{'a', 'b'}) = foo();
+(\@h{2, 3}) = foo();
+(\local @h{'a', 'b'}) = (\$x) x 2;
+\@_ = foo();
+\@a = foo();
+(\@_) = foo();
+(\@a) = foo();
+\my @c = foo();
+(\my @d) = foo();
+(\(@_)) = foo();
+(\(@a)) = foo();
+(\(my @g)) = foo();
+\local @_ = \@_;
+(\local @_) = \@_;
+\state @e = [1..3];
+(\(state @f)) = \3;
+\our @i = [1..3];
+(\(our @h)) = \3;
+\%_ = foo();
+\%h = foo();
+(\%_) = foo();
+(\%h) = foo();
+\my %c = foo();
+(\my %d) = foo();
+\local %_ = \%h;
+(\local %_) = \%h;
+\state %y = {1, 2};
+\our %z = {1, 2};
+(\our %zz) = {1, 2};
+\&a = foo();
+(\&a) = foo();
+(\&a) = foo();
+{
+  my sub a;
+  \&a = foo();
+  (\&a) = foo();
+  (\&a) = foo();
+}
+(\$_, $_) = \(1, 2);
+$_ == 3 ? \$_ : $_ = \3;
+$_ == 3 ? \$_ : \$x = \3;
+($_ == 3 ? \$_ : \$x) = \3;
+foreach \my $topic (\$1, \$2) {
+    die;
+}
+foreach \state $topic (\$1, \$2) {
+    die;
+}
+foreach \our $topic (\$1, \$2) {
+    die;
+}
+foreach \$_ (\$1, \$2) {
+    die;
+}
+foreach \my @a ([1, 2], [3, 4]) {
+    die;
+}
+foreach \state @a ([1, 2], [3, 4]) {
+    die;
+}
+foreach \our @a ([1, 2], [3, 4]) {
+    die;
+}
+foreach \@_ ([1, 2], [3, 4]) {
+    die;
+}
+foreach \my %a ({5, 6}, {7, 8}) {
+    die;
+}
+foreach \our %a ({5, 6}, {7, 8}) {
+    die;
+}
+foreach \state %a ({5, 6}, {7, 8}) {
+    die;
+}
+foreach \%_ ({5, 6}, {7, 8}) {
+    die;
+}
+{
+    my sub a;
+    foreach \&a (sub { 9; } , sub { 10; } ) {
+        die;
+    }
+}
+foreach \&a (sub { 9; } , sub { 10; } ) {
+    die;
+}
diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm
index 19e9561..5586ec7 100644
--- a/lib/B/Op_private.pm
+++ b/lib/B/Op_private.pm
@@ -128,7 +128,9 @@ $bits{$_}{5} = 'OPpHUSH_VMSISH' for qw(dbstate nextstate);
 $bits{$_}{2} = 'OPpITER_REVERSED' for qw(enteriter iter);
 $bits{$_}{7} = 'OPpLVALUE' for qw(leave leaveloop);
 $bits{$_}{4} = 'OPpLVAL_DEFER' for qw(aelem helem);
-$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter 
entersub gvsv helem hslice list padav padhv padrange padsv pushmark rv2av rv2gv 
rv2hv rv2sv);
+$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter 
entersub gvsv helem hslice list lvavref lvref lvrefslice padav padhv padrange 
padsv pushmark refassign rv2av rv2gv rv2hv  ... [7 chars truncated]
+$bits{$_}{2} = 'OPpLVREF_ELEM' for qw(lvref refassign);
+$bits{$_}{3} = 'OPpLVREF_ITER' for qw(lvref refassign);
 $bits{$_}{3} = 'OPpMAYBE_LVSUB' for qw(aassign aelem aslice av2arylen helem 
hslice keys kvaslice kvhslice padav padhv pos rkeys rv2av rv2gv rv2hv substr 
vec);
 $bits{$_}{6} = 'OPpMAYBE_TRUEBOOL' for qw(padhv rv2hv);
 $bits{$_}{7} = 'OPpOFFBYONE' for qw(caller runcv wantarray);
@@ -137,7 +139,7 @@ $bits{$_}{4} = 'OPpOPEN_IN_RAW' for qw(backtick open);
 $bits{$_}{7} = 'OPpOPEN_OUT_CRLF' for qw(backtick open);
 $bits{$_}{6} = 'OPpOPEN_OUT_RAW' for qw(backtick open);
 $bits{$_}{4} = 'OPpOUR_INTRO' for qw(enteriter gvsv rv2av rv2hv rv2sv split);
-$bits{$_}{4} = 'OPpPAD_STATE' for qw(padav padhv padsv pushmark);
+$bits{$_}{4} = 'OPpPAD_STATE' for qw(lvavref lvref padav padhv padsv pushmark 
refassign);
 $bits{$_}{7} = 'OPpPV_IS_UTF8' for qw(dump goto last next redo);
 $bits{$_}{6} = 'OPpREFCOUNTED' for qw(leave leaveeval leavesub leavesublv 
leavewrite);
 $bits{$_}{6} = 'OPpRUNTIME' for qw(match pushre qr subst substcont);
@@ -206,6 +208,18 @@ my @bf = (
             3, 'OPpDEREF_SV', 'DREFSV',
         ],
     },
+    {
+        mask_def  => 'OPpLVREF_TYPE',
+        bitmin    => 5,
+        bitmax    => 6,
+        bitmask   => 96,
+        enum      => [
+            0, 'OPpLVREF_SV', 'SV',
+            1, 'OPpLVREF_AV', 'AV',
+            2, 'OPpLVREF_HV', 'HV',
+            3, 'OPpLVREF_CV', 'CV',
+        ],
+    },
 );
 
 @{$bits{aassign}}{6,1,0} = ('OPpASSIGN_COMMON', $bf[1], $bf[1]);
@@ -381,6 +395,8 @@ $bits{log}{0} = $bf[0];
 @{$bits{lslice}}{1,0} = ($bf[1], $bf[1]);
 $bits{lstat}{0} = $bf[0];
 @{$bits{lt}}{1,0} = ($bf[1], $bf[1]);
+$bits{lvavref}{0} = $bf[0];
+@{$bits{lvref}}{6,5,0} = ($bf[7], $bf[7], $bf[0]);
 $bits{mapwhile}{0} = $bf[0];
 $bits{method}{0} = $bf[0];
 $bits{method_named}{0} = $bf[0];
@@ -427,6 +443,7 @@ $bits{readlink}{0} = $bf[0];
 @{$bits{recv}}{3,2,1,0} = ($bf[3], $bf[3], $bf[3], $bf[3]);
 $bits{redo}{0} = $bf[0];
 $bits{ref}{0} = $bf[0];
+@{$bits{refassign}}{6,5,1,0} = ($bf[7], $bf[7], $bf[1], $bf[1]);
 $bits{refgen}{0} = $bf[0];
 $bits{regcmaybe}{0} = $bf[0];
 $bits{regcomp}{0} = $bf[0];
@@ -576,6 +593,13 @@ our %defines = (
     OPpLVALUE                => 128,
     OPpLVAL_DEFER            =>  16,
     OPpLVAL_INTRO            => 128,
+    OPpLVREF_AV              =>  32,
+    OPpLVREF_CV              =>  96,
+    OPpLVREF_ELEM            =>   4,
+    OPpLVREF_HV              =>  64,
+    OPpLVREF_ITER            =>   8,
+    OPpLVREF_SV              =>   0,
+    OPpLVREF_TYPE            =>  96,
     OPpMAYBE_LVSUB           =>   8,
     OPpMAYBE_TRUEBOOL        =>  64,
     OPpMAY_RETURN_CONSTANT   =>  64,
@@ -661,6 +685,12 @@ our %labels = (
     OPpLVALUE                => 'LV',
     OPpLVAL_DEFER            => 'LVDEFER',
     OPpLVAL_INTRO            => 'LVINTRO',
+    OPpLVREF_AV              => 'AV',
+    OPpLVREF_CV              => 'CV',
+    OPpLVREF_ELEM            => 'ELEM',
+    OPpLVREF_HV              => 'HV',
+    OPpLVREF_ITER            => 'ITER',
+    OPpLVREF_SV              => 'SV',
     OPpMAYBE_LVSUB           => 'LVSUB',
     OPpMAYBE_TRUEBOOL        => 'BOOL?',
     OPpMAY_RETURN_CONSTANT   => 'CONST',
diff --git a/lib/feature.pm b/lib/feature.pm
index 89765c6..3f93f23 100644
--- a/lib/feature.pm
+++ b/lib/feature.pm
@@ -5,7 +5,7 @@
 
 package feature;
 
-our $VERSION = '1.37';
+our $VERSION = '1.38';
 
 our %feature = (
     fc              => 'feature_fc',
@@ -17,6 +17,7 @@ our %feature = (
     array_base      => 'feature_arybase',
     signatures      => 'feature_signatures',
     current_sub     => 'feature___SUB__',
+    lvalue_refs     => 'feature_lvref',
     lexical_subs    => 'feature_lexsubs',
     postderef_qq    => 'feature_postderef_qq',
     unicode_eval    => 'feature_unieval',
@@ -27,7 +28,7 @@ our %feature_bundle = (
     "5.10"    => [qw(array_base say state switch)],
     "5.11"    => [qw(array_base say state switch unicode_strings)],
     "5.15"    => [qw(current_sub evalbytes fc say state switch unicode_eval 
unicode_strings)],
-    "all"     => [qw(array_base current_sub evalbytes fc lexical_subs 
postderef postderef_qq say signatures state switch unicode_eval 
unicode_strings)],
+    "all"     => [qw(array_base current_sub evalbytes fc lexical_subs 
lvalue_refs postderef postderef_qq say signatures state switch unicode_eval 
unicode_strings)],
     "default" => [qw(array_base)],
 );
 
@@ -268,6 +269,29 @@ See L<perlsub/Signatures> for details.
 
 This feature is available from Perl 5.20 onwards.
 
+=head2 The 'lvalue_refs' feature
+
+B<WARNING>: This feature is still experimental and the implementation may
+change in future versions of Perl.  For this reason, Perl will
+warn when you use the feature, unless you have explicitly disabled the
+warning:
+
+    no warnings "experimental::lvalue_refs";
+
+This enables aliasing via assignment to references:
+
+    \$a = \$b; # $a and $b now point to the same scalar
+    \@a = \@b; #                     to the same array
+    \%a = \%b;
+    \&a = \&b;
+    foreach \%hash (@array_of_hash_refs) {
+        ...
+    }
+
+See L<perlref/Assigning to References> for details.
+
+This feature is available from Perl 5.22 onwards.
+
 =head1 FEATURE BUNDLES
 
 It's possible to load multiple features together, using
diff --git a/lib/warnings.pm b/lib/warnings.pm
index a08be18..5f7a20d 100644
--- a/lib/warnings.pm
+++ b/lib/warnings.pm
@@ -5,7 +5,7 @@
 
 package warnings;
 
-our $VERSION = '1.26';
+our $VERSION = '1.27';
 
 # Verify that we're called correctly so that warnings will work.
 # see also strict.pm.
@@ -269,6 +269,8 @@ The current hierarchy is:
          |                 |
          |                 +- experimental::lexical_topic
          |                 |
+         |                 +- experimental::lvalue_refs
+         |                 |
          |                 +- experimental::postderef
          |                 |
          |                 +- experimental::regex_sets
@@ -825,13 +827,14 @@ our %Offsets = (
 
     # Warnings Categories added in Perl 5.021
 
-    'experimental::win32_perlio'=> 120,
-    'missing'          => 122,
-    'redundant'                => 124,
+    'experimental::lvalue_refs'=> 120,
+    'experimental::win32_perlio'=> 122,
+    'missing'          => 124,
+    'redundant'                => 126,
   );
 
 our %Bits = (
-    'all'              => 
"\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x15", # [0..62]
+    'all'              => 
"\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55", # [0..63]
     'ambiguous'                => 
"\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [29]
     'bareword'         => 
"\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [30]
     'closed'           => 
"\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
@@ -841,15 +844,16 @@ our %Bits = (
     'digit'            => 
"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [31]
     'exec'             => 
"\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
     'exiting'          => 
"\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
-    'experimental'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x55\x15\x01", # 
[51..58,60]
+    'experimental'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x55\x15\x05", # 
[51..58,60,61]
     'experimental::autoderef'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [56]
     'experimental::lexical_subs'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [52]
     'experimental::lexical_topic'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [53]
+    'experimental::lvalue_refs'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [60]
     'experimental::postderef'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [57]
     'experimental::regex_sets'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00", # [54]
     'experimental::signatures'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [58]
     'experimental::smartmatch'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [55]
-    'experimental::win32_perlio'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [60]
+    'experimental::win32_perlio'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [61]
     'glob'             => 
"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4]
     'illegalproto'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [47]
     'imprecision'      => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [46]
@@ -859,7 +863,7 @@ our %Bits = (
     'layer'            => 
"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
     'malloc'           => 
"\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [25]
     'misc'             => 
"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
-    'missing'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [61]
+    'missing'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [62]
     'newline'          => 
"\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
     'non_unicode'      => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [48]
     'nonchar'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [49]
@@ -876,7 +880,7 @@ our %Bits = (
     'qw'               => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", # [36]
     'recursion'                => 
"\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [18]
     'redefine'         => 
"\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [19]
-    'redundant'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [62]
+    'redundant'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40", # [63]
     'regexp'           => 
"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [20]
     'reserved'         => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00", # [37]
     'semicolon'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [38]
@@ -897,7 +901,7 @@ our %Bits = (
   );
 
 our %DeadBits = (
-    'all'              => 
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x2a", # [0..62]
+    'all'              => 
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", # [0..63]
     'ambiguous'                => 
"\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [29]
     'bareword'         => 
"\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [30]
     'closed'           => 
"\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
@@ -907,15 +911,16 @@ our %DeadBits = (
     'digit'            => 
"\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [31]
     'exec'             => 
"\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
     'exiting'          => 
"\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
-    'experimental'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xaa\x2a\x02", # 
[51..58,60]
+    'experimental'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xaa\x2a\x0a", # 
[51..58,60,61]
     'experimental::autoderef'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [56]
     'experimental::lexical_subs'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [52]
     'experimental::lexical_topic'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [53]
+    'experimental::lvalue_refs'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [60]
     'experimental::postderef'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [57]
     'experimental::regex_sets'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00", # [54]
     'experimental::signatures'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [58]
     'experimental::smartmatch'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [55]
-    'experimental::win32_perlio'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [60]
+    'experimental::win32_perlio'=> 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [61]
     'glob'             => 
"\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4]
     'illegalproto'     => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [47]
     'imprecision'      => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [46]
@@ -925,7 +930,7 @@ our %DeadBits = (
     'layer'            => 
"\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
     'malloc'           => 
"\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [25]
     'misc'             => 
"\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
-    'missing'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [61]
+    'missing'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [62]
     'newline'          => 
"\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
     'non_unicode'      => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [48]
     'nonchar'          => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [49]
@@ -942,7 +947,7 @@ our %DeadBits = (
     'qw'               => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00", # [36]
     'recursion'                => 
"\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [18]
     'redefine'         => 
"\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [19]
-    'redundant'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [62]
+    'redundant'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80", # [63]
     'regexp'           => 
"\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [20]
     'reserved'         => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00", # [37]
     'semicolon'                => 
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [38]
@@ -963,8 +968,8 @@ our %DeadBits = (
   );
 
 $NONE     = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-$DEFAULT  = 
"\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x00\x55\x15\x01", # 
[2,56,52,53,57,54,58,55,60,4,22,23,25]
-$LAST_BIT = 126 ;
+$DEFAULT  = 
"\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x00\x55\x15\x05", # 
[2,56,52,53,60,57,54,58,55,61,4,22,23,25]
+$LAST_BIT = 128 ;
 $BYTES    = 16 ;
 
 $All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
diff --git a/mg.c b/mg.c
index 9653c70..bf98374 100644
--- a/mg.c
+++ b/mg.c
@@ -2462,6 +2462,63 @@ Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
 }
 
 int
+Perl_magic_setlvref(pTHX_ SV *sv, MAGIC *mg)
+{
+    const char *bad = NULL;
+    PERL_ARGS_ASSERT_MAGIC_SETLVREF;
+    if (!SvROK(sv)) Perl_croak(aTHX_ "Assigned value is not a reference");
+    switch (mg->mg_private & OPpLVREF_TYPE) {
+    case OPpLVREF_SV:
+       if (SvTYPE(SvRV(sv)) > SVt_PVLV)
+           bad = " SCALAR";
+       break;
+    case OPpLVREF_AV:
+       if (SvTYPE(SvRV(sv)) != SVt_PVAV)
+           bad = "n ARRAY";
+       break;
+    case OPpLVREF_HV:
+       if (SvTYPE(SvRV(sv)) != SVt_PVHV)
+           bad = " HASH";
+       break;
+    case OPpLVREF_CV:
+       if (SvTYPE(SvRV(sv)) != SVt_PVCV)
+           bad = " CODE";
+    }
+    if (bad)
+       /* diag_listed_as: Assigned value is not %s reference */
+       Perl_croak(aTHX_ "Assigned value is not a%s reference", bad);
+    switch (mg->mg_obj ? SvTYPE(mg->mg_obj) : 0) {
+    case 0:
+    {
+       SV * const old = PAD_SV(mg->mg_len);
+       PAD_SETSV(mg->mg_len, SvREFCNT_inc_NN(SvRV(sv)));
+       SvREFCNT_dec(old);
+       break;
+    }
+    case SVt_PVGV:
+       gv_setref(mg->mg_obj, sv);
+       SvSETMAGIC(mg->mg_obj);
+       break;
+    case SVt_PVAV:
+       av_store((AV *)mg->mg_obj, SvIV((SV *)mg->mg_ptr),
+                SvREFCNT_inc_simple_NN(SvRV(sv)));
+       break;
+    case SVt_PVHV:
+       hv_store_ent((HV *)mg->mg_obj, (SV *)mg->mg_ptr,
+                    SvREFCNT_inc_simple_NN(SvRV(sv)), 0);
+    }
+    if (mg->mg_flags & MGf_PERSIST)
+       NOOP; /* This sv is in use as an iterator var and will be reused,
+                so we must leave the magic.  */
+    else
+       /* This sv could be returned by the assignment op, so clear the
+          magic, as lvrefs are an implementation detail that must not be
+          leaked to the user.  */
+       sv_unmagic(sv, PERL_MAGIC_lvref);
+    return 0;
+}
+
+int
 Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
 {
 #ifdef USE_ITHREADS
diff --git a/mg.h b/mg.h
index 0f2fa29..3aa2401 100644
--- a/mg.h
+++ b/mg.h
@@ -40,6 +40,7 @@ struct magic {
 #define MGf_DUP     0x10       /* has an svt_dup   MGVTBL entry */
 #define MGf_LOCAL   0x20       /* has an svt_local MGVTBL entry */
 #define MGf_BYTES   0x40        /* PERL_MAGIC_regex_global only */
+#define MGf_PERSIST    0x80     /* PERL_MAGIC_lvref only */
 
 #define MgTAINTEDDIR(mg)       (mg->mg_flags & MGf_TAINTEDDIR)
 #define MgTAINTEDDIR_on(mg)    (mg->mg_flags |= MGf_TAINTEDDIR)
diff --git a/mg_names.c b/mg_names.c
index 52eed71..237dfc5 100644
--- a/mg_names.c
+++ b/mg_names.c
@@ -47,6 +47,7 @@
        { PERL_MAGIC_utf8,           "utf8(w)" },
        { PERL_MAGIC_substr,         "substr(x)" },
        { PERL_MAGIC_defelem,        "defelem(y)" },
+       { PERL_MAGIC_lvref,          "lvref(\\)" },
        { PERL_MAGIC_checkcall,      "checkcall(])" },
        { PERL_MAGIC_ext,            "ext(~)" },
 
diff --git a/mg_raw.h b/mg_raw.h
index 984f1d7..4b3d35d 100644
--- a/mg_raw.h
+++ b/mg_raw.h
@@ -11,7 +11,7 @@
     { '#', "want_vtbl_arylen | PERL_MAGIC_VALUE_MAGIC",
       "/* arylen '#' Array length ($#ary) */" },
     { '%', "magic_vtable_max | PERL_MAGIC_VALUE_MAGIC",
-      "/* rhash '%' extra data for restricted hashes */" },
+      "/* rhash '%' Extra data for restricted hashes */" },
     { '&', "magic_vtable_max",
       "/* proto '&' my sub prototype CV */" },
     { '*', "want_vtbl_debugvar",
@@ -19,11 +19,11 @@
     { '.', "want_vtbl_pos | PERL_MAGIC_VALUE_MAGIC",
       "/* pos '.' pos() lvalue */" },
     { ':', "magic_vtable_max | PERL_MAGIC_VALUE_MAGIC",
-      "/* symtab ':' extra data for symbol tables */" },
+      "/* symtab ':' Extra data for symbol tables */" },
     { '<', "want_vtbl_backref | PERL_MAGIC_READONLY_ACCEPTABLE | 
PERL_MAGIC_VALUE_MAGIC",
-      "/* backref '<' for weak ref data */" },
+      "/* backref '<' For weak ref data */" },
     { '@', "magic_vtable_max | PERL_MAGIC_VALUE_MAGIC",
-      "/* arylen_p '@' to move arylen out of XPVAV */" },
+      "/* arylen_p '@' To move arylen out of XPVAV */" },
     { 'B', "want_vtbl_regexp | PERL_MAGIC_READONLY_ACCEPTABLE | 
PERL_MAGIC_VALUE_MAGIC",
       "/* bm 'B' Boyer-Moore (fast string search) */" },
     { 'c', "want_vtbl_ovrld",
@@ -63,7 +63,7 @@
     { 'q', "want_vtbl_packelem",
       "/* tiedscalar 'q' Tied scalar or handle */" },
     { 'r', "want_vtbl_regexp | PERL_MAGIC_READONLY_ACCEPTABLE | 
PERL_MAGIC_VALUE_MAGIC",
-      "/* qr 'r' precompiled qr// regex */" },
+      "/* qr 'r' Precompiled qr// regex */" },
     { 'S', "magic_vtable_max",
       "/* sig 'S' %SIG hash */" },
     { 's', "want_vtbl_sigelem",
@@ -82,8 +82,10 @@
       "/* substr 'x' substr() lvalue */" },
     { 'y', "want_vtbl_defelem | PERL_MAGIC_VALUE_MAGIC",
       "/* defelem 'y' Shadow \"foreach\" iterator variable / smart parameter 
vivification */" },
+    { '\\', "want_vtbl_lvref",
+      "/* lvref '\\' Lvalue reference in list assignment */" },
     { ']', "want_vtbl_checkcall | PERL_MAGIC_VALUE_MAGIC",
-      "/* checkcall ']' inlining/mutation of call to this CV */" },
+      "/* checkcall ']' Inlining/mutation of call to this CV */" },
     { '~', "magic_vtable_max",
       "/* ext '~' Available for use by extensions */" },
 
diff --git a/mg_vtable.h b/mg_vtable.h
index 104e936..2ee6361 100644
--- a/mg_vtable.h
+++ b/mg_vtable.h
@@ -14,13 +14,13 @@
 
 #define PERL_MAGIC_sv             '\0' /* Special scalar variable */
 #define PERL_MAGIC_arylen         '#' /* Array length ($#ary) */
-#define PERL_MAGIC_rhash          '%' /* extra data for restricted hashes */
+#define PERL_MAGIC_rhash          '%' /* Extra data for restricted hashes */
 #define PERL_MAGIC_proto          '&' /* my sub prototype CV */
 #define PERL_MAGIC_debugvar       '*' /* $DB::single, signal, trace vars */
 #define PERL_MAGIC_pos            '.' /* pos() lvalue */
-#define PERL_MAGIC_symtab         ':' /* extra data for symbol tables */
-#define PERL_MAGIC_backref        '<' /* for weak ref data */
-#define PERL_MAGIC_arylen_p       '@' /* to move arylen out of XPVAV */
+#define PERL_MAGIC_symtab         ':' /* Extra data for symbol tables */
+#define PERL_MAGIC_backref        '<' /* For weak ref data */
+#define PERL_MAGIC_arylen_p       '@' /* To move arylen out of XPVAV */
 #define PERL_MAGIC_bm             'B' /* Boyer-Moore (fast string search) */
 #define PERL_MAGIC_overload_table 'c' /* Holds overload table (AMT) on stash */
 #define PERL_MAGIC_regdata        'D' /* Regex match position data
@@ -43,7 +43,7 @@
 #define PERL_MAGIC_tied           'P' /* Tied array or hash */
 #define PERL_MAGIC_tiedelem       'p' /* Tied array or hash element */
 #define PERL_MAGIC_tiedscalar     'q' /* Tied scalar or handle */
-#define PERL_MAGIC_qr             'r' /* precompiled qr// regex */
+#define PERL_MAGIC_qr             'r' /* Precompiled qr// regex */
 #define PERL_MAGIC_sig            'S' /* %SIG hash */
 #define PERL_MAGIC_sigelem        's' /* %SIG hash element */
 #define PERL_MAGIC_taint          't' /* Taintedness */
@@ -55,7 +55,8 @@
 #define PERL_MAGIC_substr         'x' /* substr() lvalue */
 #define PERL_MAGIC_defelem        'y' /* Shadow "foreach" iterator variable /
                                          smart parameter vivification */
-#define PERL_MAGIC_checkcall      ']' /* inlining/mutation of call to this CV 
*/
+#define PERL_MAGIC_lvref          '\\' /* Lvalue reference in list assignment 
*/
+#define PERL_MAGIC_checkcall      ']' /* Inlining/mutation of call to this CV 
*/
 #define PERL_MAGIC_ext            '~' /* Available for use by extensions */
 
 enum {         /* pass one of these to get_vtbl */
@@ -73,6 +74,7 @@ enum {                /* pass one of these to get_vtbl */
     want_vtbl_hintselem,
     want_vtbl_isa,
     want_vtbl_isaelem,
+    want_vtbl_lvref,
     want_vtbl_mglob,
     want_vtbl_nkeys,
     want_vtbl_ovrld,
@@ -108,6 +110,7 @@ EXTCONST char * const 
PL_magic_vtable_names[magic_vtable_max] = {
     "hintselem",
     "isa",
     "isaelem",
+    "lvref",
     "mglob",
     "nkeys",
     "ovrld",
@@ -166,6 +169,7 @@ EXT_MGVTBL PL_magic_vtables[magic_vtable_max] = {
   { 0, Perl_magic_sethint, 0, Perl_magic_clearhint, 0, 0, 0, 0 },
   { 0, Perl_magic_setisa, 0, Perl_magic_clearisa, 0, 0, 0, 0 },
   { 0, Perl_magic_setisa, 0, 0, 0, 0, 0, 0 },
+  { 0, Perl_magic_setlvref, 0, 0, 0, 0, 0, 0 },
   { 0, Perl_magic_setmglob, 0, 0, 0, 0, 0, 0 },
   { Perl_magic_getnkeys, Perl_magic_setnkeys, 0, 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, Perl_magic_freeovrld, 0, 0, 0 },
@@ -210,6 +214,7 @@ EXT_MGVTBL PL_magic_vtables[magic_vtable_max];
 #define PL_vtbl_hintselem PL_magic_vtables[want_vtbl_hintselem]
 #define PL_vtbl_isa PL_magic_vtables[want_vtbl_isa]
 #define PL_vtbl_isaelem PL_magic_vtables[want_vtbl_isaelem]
+#define PL_vtbl_lvref PL_magic_vtables[want_vtbl_lvref]
 #define PL_vtbl_mglob PL_magic_vtables[want_vtbl_mglob]
 #define PL_vtbl_nkeys PL_magic_vtables[want_vtbl_nkeys]
 #define PL_vtbl_ovrld PL_magic_vtables[want_vtbl_ovrld]
diff --git a/op.c b/op.c
index 1496db5..d763b62 100644
--- a/op.c
+++ b/op.c
@@ -1802,7 +1802,8 @@ Perl_scalarvoid(pTHX_ OP *o)
 
        refgen = (UNOP *)((BINOP *)o)->op_first;
 
-       if (!refgen || refgen->op_type != OP_REFGEN)
+       if (!refgen || (refgen->op_type != OP_REFGEN
+                       && refgen->op_type != OP_SREFGEN))
            break;
 
        exlist = (LISTOP *)refgen->op_first;
@@ -1810,7 +1811,8 @@ Perl_scalarvoid(pTHX_ OP *o)
            || exlist->op_targ != OP_LIST)
            break;
 
-       if (exlist->op_first->op_type != OP_PUSHMARK)
+       if (exlist->op_first->op_type != OP_PUSHMARK
+        && exlist->op_first != exlist->op_last)
            break;
 
        rv2cv = (UNOP*)exlist->op_last;
@@ -2333,6 +2335,130 @@ S_vivifies(const OPCODE type)
     return 0;
 }
 
+static void
+S_lvref(pTHX_ OP *o, I32 type)
+{
+    OP *kid;
+    switch (o->op_type) {
+    case OP_COND_EXPR:
+       for (kid = OP_SIBLING(cUNOPo->op_first); kid;
+            kid = OP_SIBLING(kid))
+           S_lvref(aTHX_ kid, type);
+       /* FALLTHROUGH */
+    case OP_PUSHMARK:
+       return;
+    case OP_RV2AV:
+       if (cUNOPo->op_first->op_type != OP_GV) goto badref;
+       o->op_flags |= OPf_STACKED;
+       if (o->op_flags & OPf_PARENS) {
+           if (o->op_private & OPpLVAL_INTRO) {
+                /* diag_listed_as: Can't modify %s in %s */
+                yyerror(Perl_form(aTHX_ "Can't modify reference to "
+                     "localized parenthesized array in list assignment"));
+               return;
+           }
+         slurpy:
+           o->op_type = OP_LVAVREF;
+           o->op_ppaddr = PL_ppaddr[OP_LVAVREF];
+           o->op_private &= OPpLVAL_INTRO|OPpPAD_STATE;
+           o->op_flags |= OPf_MOD|OPf_REF;
+           return;
+       }
+       o->op_private |= OPpLVREF_AV;
+       goto checkgv;
+    case OP_RV2CV:
+       kid = cUNOPo->op_first;
+       if (kid->op_type == OP_NULL)
+           kid = cUNOPx(kUNOP->op_first->op_sibling)
+               ->op_first;
+       o->op_private = OPpLVREF_CV;
+       if (kid->op_type == OP_GV)
+           o->op_flags |= OPf_STACKED;
+       else if (kid->op_type == OP_PADCV) {
+           o->op_targ = kid->op_targ;
+           kid->op_targ = 0;
+           op_free(cUNOPo->op_first);
+           cUNOPo->op_first = NULL;
+           o->op_flags &=~ OPf_KIDS;
+       }
+       else goto badref;
+       break;
+    case OP_RV2HV:
+       if (o->op_flags & OPf_PARENS) {
+         parenhash:
+           /* diag_listed_as: Can't modify %s in %s */
+           yyerror(Perl_form(aTHX_ "Can't modify reference to "
+                                "parenthesized hash in list assignment"));
+               return;
+       }
+       o->op_private |= OPpLVREF_HV;
+       /* FALLTHROUGH */
+    case OP_RV2SV:
+      checkgv:
+       if (cUNOPo->op_first->op_type != OP_GV) goto badref;
+       o->op_flags |= OPf_STACKED;
+       break;
+    case OP_PADHV:
+       if (o->op_flags & OPf_PARENS) goto parenhash;
+       o->op_private |= OPpLVREF_HV;
+       /* FALLTHROUGH */
+    case OP_PADSV:
+       PAD_COMPNAME_GEN_set(o->op_targ, PERL_INT_MAX);
+       break;
+    case OP_PADAV:
+       PAD_COMPNAME_GEN_set(o->op_targ, PERL_INT_MAX);
+       if (o->op_flags & OPf_PARENS) goto slurpy;
+       o->op_private |= OPpLVREF_AV;
+       break;
+    case OP_AELEM:
+    case OP_HELEM:
+       o->op_private |= OPpLVREF_ELEM;
+       o->op_flags   |= OPf_STACKED;
+       break;
+    case OP_ASLICE:
+    case OP_HSLICE:
+       o->op_type = OP_LVREFSLICE;
+       o->op_ppaddr = PL_ppaddr[OP_LVREFSLICE];
+       o->op_private &= OPpLVAL_INTRO|OPpLVREF_ELEM;
+       return;
+    case OP_NULL:
+       if (o->op_flags & OPf_SPECIAL)          /* do BLOCK */
+           goto badref;
+       else if (!(o->op_flags & OPf_KIDS))
+           return;
+       if (o->op_targ != OP_LIST) {
+           S_lvref(aTHX_ cBINOPo->op_first, type);
+           return;
+       }
+       /* FALLTHROUGH */
+    case OP_LIST:
+       for (kid = cLISTOPo->op_first; kid; kid = OP_SIBLING(kid)) {
+           assert((kid->op_flags & OPf_WANT) != OPf_WANT_VOID);
+           S_lvref(aTHX_ kid, type);
+       }
+       return;
+    case OP_STUB:
+       if (o->op_flags & OPf_PARENS)
+           return;
+       /* FALLTHROUGH */
+    default:
+      badref:
+       /* diag_listed_as: Can't modify %s in %s */
+       yyerror(Perl_form(aTHX_ "Can't modify reference to %s in %s",
+                    o->op_type == OP_NULL && o->op_flags & OPf_SPECIAL
+                     ? "do block"
+                     : OP_DESC(o),
+                    PL_op_desc[type]));
+       return;
+    }
+    o->op_type = OP_LVREF;
+    o->op_ppaddr = PL_ppaddr[OP_LVREF];
+    o->op_private &=
+       OPpLVAL_INTRO|OPpLVREF_ELEM|OPpLVREF_TYPE|OPpPAD_STATE;
+    if (type == OP_ENTERLOOP)
+       o->op_private |= OPpLVREF_ITER;
+}
+
 OP *
 Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
 {
@@ -2626,6 +2752,35 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
         || !S_vivifies(OP_SIBLING(cLOGOPo->op_first)->op_type))
            op_lvalue(OP_SIBLING(cLOGOPo->op_first), type);
        goto nomod;
+
+    case OP_SREFGEN:
+       if (type != OP_AASSIGN && type != OP_SASSIGN
+        && type != OP_ENTERLOOP)
+           goto nomod;
+       /* Don’t bother applying lvalue context to the ex-list.  */
+       kid = cUNOPx(cUNOPo->op_first)->op_first;
+       assert (!OP_HAS_SIBLING(kid));
+       goto kid_2lvref;
+    case OP_REFGEN:
+       if (type != OP_AASSIGN) goto nomod;
+       kid = cUNOPo->op_first;
+      kid_2lvref:
+       {
+           const U8 ec = PL_parser ? PL_parser->error_count : 0;
+           S_lvref(aTHX_ kid, type);
+           if (!PL_parser || PL_parser->error_count == ec) {
+               if (!FEATURE_LVREF_IS_ENABLED)
+                   Perl_croak(aTHX_
+                            "Experimental lvalue references not enabled");
+               Perl_ck_warner_d(aTHX_
+                                packWARN(WARN_EXPERIMENTAL__LVALUE_REFS),
+                             "Lvalue references are experimental");
+           }
+       }
+       if (o->op_type == OP_REFGEN)
+           op_null(cUNOPx(cUNOPo->op_first)->op_first); /* pushmark */
+       op_null(o);
+       return o;
     }
 
     /* [20011101.069] File test operators interpret OPf_REF to mean that
@@ -4410,16 +4565,16 @@ Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first, OP 
*last)
         last->op_sibling = (OP*)binop;
 #endif
 
-    binop = (BINOP*)CHECKOP(type, binop);
-    if (binop->op_next || binop->op_type != (OPCODE)type)
-       return (OP*)binop;
-
     binop->op_last = OP_SIBLING(binop->op_first);
 #ifdef PERL_OP_PARENT
     if (binop->op_last)
         binop->op_last->op_sibling = (OP*)binop;
 #endif
 
+    binop = (BINOP*)CHECKOP(type, binop);
+    if (binop->op_next || binop->op_type != (OPCODE)type)
+       return (OP*)binop;
+
     return fold_constants(op_integerize(op_std_init((OP *)binop)));
 }
 
@@ -5661,11 +5816,15 @@ Perl_newSLICEOP(pTHX_ I32 flags, OP *subscript, OP 
*listval)
            list(force_list(listval,   1)) );
 }
 
+#define ASSIGN_LIST   1
+#define ASSIGN_REF    2
+
 STATIC I32
-S_is_list_assignment(pTHX_ const OP *o)
+S_assignment_type(pTHX_ const OP *o)
 {
     unsigned type;
     U8 flags;
+    U8 ret;
 
     if (!o)
        return TRUE;
@@ -5677,40 +5836,72 @@ S_is_list_assignment(pTHX_ const OP *o)
     type = o->op_type;
     if (type == OP_COND_EXPR) {
         OP * const sib = OP_SIBLING(cLOGOPo->op_first);
-        const I32 t = is_list_assignment(sib);
-        const I32 f = is_list_assignment(OP_SIBLING(sib));
+        const I32 t = assignment_type(sib);
+        const I32 f = assignment_type(OP_SIBLING(sib));
 
-       if (t && f)
-           return TRUE;
-       if (t || f)
+       if (t == ASSIGN_LIST && f == ASSIGN_LIST)
+           return ASSIGN_LIST;
+       if ((t == ASSIGN_LIST) ^ (f == ASSIGN_LIST))
            yyerror("Assignment to both a list and a scalar");
        return FALSE;
     }
 
+    if (type == OP_SREFGEN)
+    {
+       OP * const kid = cUNOPx(cUNOPo->op_first)->op_first;
+       type = kid->op_type;
+       flags |= kid->op_flags;
+       if (!(flags & OPf_PARENS)
+         && (kid->op_type == OP_RV2AV || kid->op_type == OP_PADAV ||
+             kid->op_type == OP_RV2HV || kid->op_type == OP_PADHV ))
+           return ASSIGN_REF;
+       ret = ASSIGN_REF;
+    }
+    else ret = 0;
+
     if (type == OP_LIST &&
        (flags & OPf_WANT) == OPf_WANT_SCALAR &&
        o->op_private & OPpLVAL_INTRO)
-       return FALSE;
+       return ret;
 
     if (type == OP_LIST || flags & OPf_PARENS ||
        type == OP_RV2AV || type == OP_RV2HV ||
        type == OP_ASLICE || type == OP_HSLICE ||
-        type == OP_KVASLICE || type == OP_KVHSLICE)
+        type == OP_KVASLICE || type == OP_KVHSLICE || type == OP_REFGEN)
        return TRUE;
 
     if (type == OP_PADAV || type == OP_PADHV)
        return TRUE;
 
     if (type == OP_RV2SV)
-       return FALSE;
+       return ret;
 
-    return FALSE;
+    return ret;
 }
 
 /*
   Helper function for newASSIGNOP to detection commonality between the
-  lhs and the rhs.  Marks all variables with PL_generation.  If it
+  lhs and the rhs.  (It is actually called very indirectly.  newASSIGNOP
+  flags the op and the peephole optimizer calls this helper function
+  if the flag is set.)  Marks all variables with PL_generation.  If it
   returns TRUE the assignment must be able to handle common variables.
+
+  PL_generation sorcery:
+  An assignment like ($a,$b) = ($c,$d) is easier than
+  ($a,$b) = ($c,$a), since there is no need for temporary vars.
+  To detect whether there are common vars, the global var
+  PL_generation is incremented for each assign op we compile.
+  Then, while compiling the assign op, we run through all the
+  variables on both sides of the assignment, setting a spare slot
+  in each of them to PL_generation.  If any of them already have
+  that value, we know we've got commonality.  Also, if the
+  generation number is already set to PERL_INT_MAX, then
+  the variable is involved in aliasing, so we also have
+  potential commonality in that case.  We could use a
+  single bit marker, but then we'd have to make 2 passes, first
+  to clear the flag, then to test and set it.  And that
+  wouldn't help with aliasing, either.  To find somewhere
+  to store these values, evil chicanery is done with SvUVX().
 */
 PERL_STATIC_INLINE bool
 S_aassign_common_vars(pTHX_ OP* o)
@@ -5718,7 +5909,7 @@ S_aassign_common_vars(pTHX_ OP* o)
     OP *curop;
     for (curop = cUNOPo->op_first; curop; curop = OP_SIBLING(curop)) {
        if (PL_opargs[curop->op_type] & OA_DANGEROUS) {
-           if (curop->op_type == OP_GV) {
+           if (curop->op_type == OP_GV || curop->op_type == OP_GVSV) {
                GV *gv = cGVOPx_gv(curop);
                if (gv == PL_defgv
                    || (int)GvASSIGN_GENERATION(gv) == PL_generation)
@@ -5731,7 +5922,8 @@ S_aassign_common_vars(pTHX_ OP* o)
                curop->op_type == OP_PADANY)
                {
                    if (PAD_COMPNAME_GEN(curop->op_targ)
-                       == (STRLEN)PL_generation)
+                       == (STRLEN)PL_generation
+                    || PAD_COMPNAME_GEN(curop->op_targ) == PERL_INT_MAX)
                        return TRUE;
                    PAD_COMPNAME_GEN_set(curop->op_targ, PL_generation);
 
@@ -5761,6 +5953,9 @@ S_aassign_common_vars(pTHX_ OP* o)
                    GvASSIGN_GENERATION_set(gv, PL_generation);
                }
            }
+           else if (curop->op_type == OP_PADRANGE)
+               /* Ignore padrange; checking its siblings is sufficient. */
+               continue;
            else
                return TRUE;
        }
@@ -5773,6 +5968,29 @@ S_aassign_common_vars(pTHX_ OP* o)
     return FALSE;
 }
 
+/* This variant only handles lexical aliases.  It is called when
+   newASSIGNOP decides that we don’t have any common vars, as lexical ali-
+   ases trump that decision.  */
+PERL_STATIC_INLINE bool
+S_aassign_common_vars_aliases_only(pTHX_ OP *o)
+{
+    OP *curop;
+    for (curop = cUNOPo->op_first; curop; curop = OP_SIBLING(curop)) {
+       if ((curop->op_type == OP_PADSV ||
+            curop->op_type == OP_PADAV ||
+            curop->op_type == OP_PADHV ||
+            curop->op_type == OP_PADANY)
+          && PAD_COMPNAME_GEN(curop->op_targ) == PERL_INT_MAX)
+           return TRUE;
+
+       if (curop->op_flags & OPf_KIDS) {
+           if (S_aassign_common_vars_aliases_only(aTHX_ curop))
+               return TRUE;
+       }
+    }
+    return FALSE;
+}
+
 /*
 =for apidoc Am|OP *|newASSIGNOP|I32 flags|OP *left|I32 optype|OP *right
 
@@ -5800,6 +6018,7 @@ OP *
 Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
 {
     OP *o;
+    I32 assign_type;
 
     if (optype) {
        if (optype == OP_ANDASSIGN || optype == OP_ORASSIGN || optype == 
OP_DORASSIGN) {
@@ -5813,7 +6032,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
        }
     }
 
-    if (is_list_assignment(left)) {
+    if ((assign_type = assignment_type(left)) == ASSIGN_LIST) {
        static const char no_list_state[] = "Initialization of state variables"
            " in list context currently forbidden";
        OP *curop;
@@ -5838,7 +6057,10 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
                    lop->op_type == OP_PADHV ||
                    lop->op_type == OP_PADANY) {
                    if (!(lop->op_private & OPpLVAL_INTRO))
+                   {
                        maybe_common_vars = TRUE;
+                       break;
+                   }
 
                    if (lop->op_private & OPpPAD_STATE) {
                        if (left->op_private & OPpLVAL_INTRO) {
@@ -5860,6 +6082,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
                } else {
                    /* Other ops in the list. */
                    maybe_common_vars = TRUE;
+                   break;
                }
                lop = OP_SIBLING(lop);
            }
@@ -5886,25 +6109,10 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
            }
        }
 
-       /* PL_generation sorcery:
-        * an assignment like ($a,$b) = ($c,$d) is easier than
-        * ($a,$b) = ($c,$a), since there is no need for temporary vars.
-        * To detect whether there are common vars, the global var
-        * PL_generation is incremented for each assign op we compile.
-        * Then, while compiling the assign op, we run through all the
-        * variables on both sides of the assignment, setting a spare slot
-        * in each of them to PL_generation. If any of them already have
-        * that value, we know we've got commonality.  We could use a
-        * single bit marker, but then we'd have to make 2 passes, first
-        * to clear the flag, then to test and set it.  To find somewhere
-        * to store these values, evil chicanery is done with SvUVX().
-        */
-
        if (maybe_common_vars) {
-           PL_generation++;
-           if (aassign_common_vars(o))
+               /* The peephole optimizer will do the full check and pos-
+                  sibly turn this off.  */
                o->op_private |= OPpASSIGN_COMMON;
-           LINKLIST(o);
        }
 
        if (right && right->op_type == OP_SPLIT) {
@@ -5912,8 +6120,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
            if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
                PMOP * const pm = (PMOP*)tmpop;
                if (left->op_type == OP_RV2AV &&
-                   !(left->op_private & OPpLVAL_INTRO) &&
-                   !(o->op_private & OPpASSIGN_COMMON) )
+                   !(left->op_private & OPpLVAL_INTRO))
                {
                    tmpop = ((UNOP*)left)->op_first;
                    if (tmpop->op_type == OP_GV
@@ -5937,7 +6144,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
                         /* detach rest of siblings from o subtree,
                          * and free subtree */
                         op_sibling_splice(cUNOPo->op_first, tmpop, -1, NULL);
-                       right->op_next = tmpop->op_next;  /* fix starting loc */
                        right->op_private |=
                            left->op_private & OPpOUR_INTRO;
                        op_free(o);                     /* blow off assign */
@@ -5972,6 +6178,8 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, 
OP *right)
        }
        return o;
     }
+    if (assign_type == ASSIGN_REF)
+       return newBINOP(OP_REFASSIGN, flags, scalar(right), left);
     if (!right)
        right = newOP(OP_UNDEF, 0);
     if (right->op_type == OP_READLINE) {
@@ -6765,7 +6973,10 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP 
*block, OP *cont)
             sv->op_targ = 0;
             op_free(sv);
            sv = NULL;
+           PAD_COMPNAME_GEN_set(padoff, PERL_INT_MAX);
        }
+       else if (sv->op_type == OP_NULL && sv->op_targ == OP_SREFGEN)
+           NOOP;
        else
            Perl_croak(aTHX_ "Can't use %s for loop variable", 
PL_op_desc[sv->op_type]);
        if (padoff) {
@@ -8867,9 +9078,14 @@ Perl_ck_spair(pTHX_ OP *o)
        newop = OP_SIBLING(kidkid);
        if (newop) {
            const OPCODE type = newop->op_type;
-           if (OP_HAS_SIBLING(newop) || !(PL_opargs[type] & OA_RETSCALAR) ||
-                   type == OP_PADAV || type == OP_PADHV ||
-                   type == OP_RV2AV || type == OP_RV2HV)
+           if (OP_HAS_SIBLING(newop))
+               return o;
+           if (o->op_type == OP_REFGEN && !(newop->op_flags & OPf_PARENS)
+               && (type == OP_RV2AV || type == OP_PADAV
+                || type == OP_RV2HV || type == OP_PADHV
+                || type == OP_RV2CV))
+               NOOP; /* OK (allow srefgen for \@a and \%h) */
+           else if (!(PL_opargs[type] & OA_RETSCALAR))
                return o;
        }
         /* excise first sibling */
@@ -9759,23 +9975,18 @@ Perl_ck_sassign(pTHX_ OP *o)
            OP *const first = newOP(OP_NULL, 0);
            OP *const nullop = newCONDOP(0, first, o, other);
            OP *const condop = first->op_next;
-           /* hijacking PADSTALE for uninitialized state variables */
-           SvPADSTALE_on(PAD_SVl(target));
 
            condop->op_type = OP_ONCE;
            condop->op_ppaddr = PL_ppaddr[OP_ONCE];
-           condop->op_targ = target;
            other->op_targ = target;
 
-           /* Because we change the type of the op here, we will skip the
-              assignment binop->op_last = OP_SIBLING(binop->op_first); at the
-              end of Perl_newBINOP(). So need to do it here. */
-           cBINOPo->op_last = OP_SIBLING(cBINOPo->op_first);
-            cBINOPo->op_first->op_lastsib = 0;
-            cBINOPo->op_last ->op_lastsib = 1;
-#ifdef PERL_OP_PARENT
-            cBINOPo->op_last->op_sibling = o;
-#endif
+           /* Store the initializedness of state vars in a separate
+              pad entry.  */
+           condop->op_targ =
+             pad_add_name_pvn("$",1,padadd_NO_DUP_CHECK|padadd_STATE,0,0);
+           /* hijacking PADSTALE for uninitialized state variables */
+           SvPADSTALE_on(PAD_SVl(condop->op_targ));
+
            return nullop;
        }
     }
@@ -9864,6 +10075,82 @@ Perl_ck_open(pTHX_ OP *o)
 }
 
 OP *
+Perl_ck_refassign(pTHX_ OP *o)
+{
+    OP * const right = cLISTOPo->op_first;
+    OP * const left = OP_SIBLING(right);
+    OP * const varop = cUNOPx(cUNOPx(left)->op_first)->op_first;
+    bool stacked = 0;
+
+    PERL_ARGS_ASSERT_CK_REFASSIGN;
+    assert (left);
+    assert (left->op_type == OP_SREFGEN);
+
+    switch (varop->op_type) {
+    case OP_PADAV:
+       o->op_private = OPpLVREF_AV;
+       goto settarg;
+    case OP_PADHV:
+       o->op_private = OPpLVREF_HV;
+    case OP_PADSV:
+      settarg:
+       o->op_targ = varop->op_targ;
+       varop->op_targ = 0;
+       PAD_COMPNAME_GEN_set(o->op_targ, PERL_INT_MAX);
+       break;
+    case OP_RV2AV:
+       o->op_private = OPpLVREF_AV;
+       goto checkgv;
+    case OP_RV2HV:
+       o->op_private = OPpLVREF_HV;
+    case OP_RV2SV:
+      checkgv:
+       if (cUNOPx(varop)->op_first->op_type != OP_GV) goto bad;
+       goto null_and_stack;
+    case OP_RV2CV: {
+       OP * const kid =
+           cUNOPx(cUNOPx(cUNOPx(varop)->op_first)->op_first->op_sibling)
+               ->op_first;
+       o->op_private = OPpLVREF_CV;
+       if (kid->op_type == OP_GV)      goto null_and_stack;
+       if (kid->op_type != OP_PADCV)   goto bad;
+       o->op_targ = kid->op_targ;
+       kid->op_targ = 0;
+       break;
+    }
+    case OP_AELEM:
+    case OP_HELEM:
+       o->op_private = OPpLVREF_ELEM;
+      null_and_stack:
+       op_null(varop);
+       op_null(left);
+       stacked = TRUE;
+       break;
+    default:
+      bad:
+       /* diag_listed_as: Can't modify %s in %s */
+       yyerror(Perl_form(aTHX_ "Can't modify reference to %s in scalar "
+                               "assignment",
+                                OP_DESC(varop)));
+       return o;
+    }
+    if (!FEATURE_LVREF_IS_ENABLED)
+       Perl_croak(aTHX_
+                 "Experimental lvalue references not enabled");
+    Perl_ck_warner_d(aTHX_
+                    packWARN(WARN_EXPERIMENTAL__LVALUE_REFS),
+                   "Lvalue references are experimental");
+    o->op_private |= varop->op_private & (OPpLVAL_INTRO|OPpPAD_STATE);
+    if (stacked) o->op_flags |= OPf_STACKED;
+    else {
+       o->op_flags &=~ OPf_STACKED;
+       op_sibling_splice(o, right, 1, NULL);
+       op_free(left);
+    }
+    return o;
+}
+
+OP *
 Perl_ck_repeat(pTHX_ OP *o)
 {
     PERL_ARGS_ASSERT_CK_REPEAT;
@@ -9874,6 +10161,7 @@ Perl_ck_repeat(pTHX_ OP *o)
         kids = op_sibling_splice(o, NULL, -1, NULL); /* detach all kids */
         kids = force_list(kids, 1); /* promote them to a list */
         op_sibling_splice(o, NULL, 0, kids); /* and add back */
+        if (cBINOPo->op_last == kids) cBINOPo->op_last = NULL;
     }
     else
        scalar(o);
@@ -10544,7 +10832,8 @@ Perl_ck_entersub_args_proto(pTHX_ OP *entersubop, GV 
*namegv, SV *protosv)
            case '&':
                proto++;
                arg++;
-               if (o3->op_type != OP_REFGEN && o3->op_type != OP_UNDEF)
+               if (o3->op_type != OP_REFGEN && o3->op_type != OP_SREFGEN
+                && o3->op_type != OP_UNDEF)
                    bad_type_gv(arg,
                            arg == 1 ? "block or sub {}" : "sub {}",
                            namegv, 0, o3);
@@ -12249,6 +12538,21 @@ Perl_rpeep(pTHX_ OP *o)
            }
            break;
 
+       case OP_AASSIGN:
+           /* We do the common-vars check here, rather than in newASSIGNOP
+              (as formerly), so that all lexical vars that get aliased are
+              marked as such before we do the check.  */
+           if (o->op_private & OPpASSIGN_COMMON) {
+                /* See the comment before S_aassign_common_vars concerning
+                   PL_generation sorcery.  */
+               PL_generation++;
+               if (!aassign_common_vars(o))
+                   o->op_private &=~ OPpASSIGN_COMMON;
+           }
+           else if (S_aassign_common_vars_aliases_only(aTHX_ o))
+               o->op_private |= OPpASSIGN_COMMON;
+           break;
+
        case OP_CUSTOM: {
            Perl_cpeep_t cpeep = 
                XopENTRYCUSTOM(o, xop_peep);
diff --git a/opcode.h b/opcode.h
index c2ff500..8117fd9 100644
--- a/opcode.h
+++ b/opcode.h
@@ -527,6 +527,10 @@ EXTCONST char* const PL_op_name[] = {
        "introcv",
        "clonecv",
        "padrange",
+       "refassign",
+       "lvref",
+       "lvrefslice",
+       "lvavref",
        "freed",
 };
 #endif
@@ -914,6 +918,10 @@ EXTCONST char* const PL_op_desc[] = {
        "private subroutine",
        "private subroutine",
        "list of private variables",
+       "lvalue ref assignment",
+       "lvalue ref assignment",
+       "lvalue ref assignment",
+       "lvalue array reference",
        "freed op",
 };
 #endif
@@ -1315,6 +1323,10 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
        Perl_pp_introcv,
        Perl_pp_clonecv,
        Perl_pp_padrange,
+       Perl_pp_refassign,
+       Perl_pp_lvref,
+       Perl_pp_lvrefslice,
+       Perl_pp_lvavref,
 }
 #endif
 #ifdef PERL_PPADDR_INITED
@@ -1712,6 +1724,10 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
        Perl_ck_null,           /* introcv */
        Perl_ck_null,           /* clonecv */
        Perl_ck_null,           /* padrange */
+       Perl_ck_refassign,      /* refassign */
+       Perl_ck_null,           /* lvref */
+       Perl_ck_null,           /* lvrefslice */
+       Perl_ck_null,           /* lvavref */
 }
 #endif
 #ifdef PERL_CHECK_INITED
@@ -2103,6 +2119,10 @@ EXTCONST U32 PL_opargs[] = {
        0x00000040,     /* introcv */
        0x00000040,     /* clonecv */
        0x00000040,     /* padrange */
+       0x00000240,     /* refassign */
+       0x00000b40,     /* lvref */
+       0x00000440,     /* lvrefslice */
+       0x00000b40,     /* lvavref */
 };
 #endif
 
@@ -2111,6 +2131,7 @@ EXTCONST U32 PL_opargs[] = {
 END_EXTERN_C
 
 
+#define OPpLVREF_SV             0x00
 #define OPpARG1_MASK            0x01
 #define OPpCOREARGS_DEREF1      0x01
 #define OPpENTERSUB_INARGS      0x01
@@ -2131,6 +2152,7 @@ END_EXTERN_C
 #define OPpEVAL_UNICODE         0x04
 #define OPpFT_STACKED           0x04
 #define OPpITER_REVERSED        0x04
+#define OPpLVREF_ELEM           0x04
 #define OPpSLICEWARNING         0x04
 #define OPpSORT_REVERSE         0x04
 #define OPpTRANS_IDENTICAL      0x04
@@ -2141,6 +2163,7 @@ END_EXTERN_C
 #define OPpEVAL_BYTES           0x08
 #define OPpFT_STACKING          0x08
 #define OPpITER_DEF             0x08
+#define OPpLVREF_ITER           0x08
 #define OPpMAYBE_LVSUB          0x08
 #define OPpREVERSE_INPLACE      0x08
 #define OPpSORT_INPLACE         0x08
@@ -2162,6 +2185,7 @@ END_EXTERN_C
 #define OPpEARLY_CV             0x20
 #define OPpEVAL_RE_REPARSING    0x20
 #define OPpHUSH_VMSISH          0x20
+#define OPpLVREF_AV             0x20
 #define OPpOPEN_IN_CRLF         0x20
 #define OPpSORT_QSORT           0x20
 #define OPpTRANS_COMPLEMENT     0x20
@@ -2175,6 +2199,7 @@ END_EXTERN_C
 #define OPpFLIP_LINENUM         0x40
 #define OPpHINT_M_VMSISH_STATUS 0x40
 #define OPpLIST_GUESSED         0x40
+#define OPpLVREF_HV             0x40
 #define OPpMAYBE_TRUEBOOL       0x40
 #define OPpMAY_RETURN_CONSTANT  0x40
 #define OPpOPEN_OUT_RAW         0x40
@@ -2186,6 +2211,8 @@ END_EXTERN_C
 #define OPpTRANS_GROWS          0x40
 #define OPpDEREF                0x60
 #define OPpDEREF_SV             0x60
+#define OPpLVREF_CV             0x60
+#define OPpLVREF_TYPE           0x60
 #define OPpPADRANGE_COUNTMASK   0x7f
 #define OPpASSIGN_CV_TO_GV      0x80
 #define OPpCOREARGS_PUSHMARK    0x80
@@ -2227,6 +2254,7 @@ EXTCONST char PL_op_private_labels[] = {
     '<','U','T','F','\0',
     '>','U','T','F','\0',
     'A','M','P','E','R','\0',
+    'A','V','\0',
     'B','A','R','E','\0',
     'B','K','W','A','R','D','\0',
     'B','O','O','L','\0',
@@ -2236,6 +2264,7 @@ EXTCONST char PL_op_private_labels[] = {
     'C','O','M','P','L','\0',
     'C','O','N','S','T','\0',
     'C','O','P','H','H','\0',
+    'C','V','\0',
     'C','V','2','G','V','\0',
     'D','B','G','\0',
     'D','E','F','\0',
@@ -2248,6 +2277,7 @@ EXTCONST char PL_op_private_labels[] = {
     'D','R','E','F','H','V','\0',
     'D','R','E','F','S','V','\0',
     'E','A','R','L','Y','C','V','\0',
+    'E','L','E','M','\0',
     'E','N','T','E','R','E','D','\0',
     'F','A','K','E','\0',
     'F','T','A','C','C','E','S','S','\0',
@@ -2259,6 +2289,7 @@ EXTCONST char PL_op_private_labels[] = {
     'G','U','E','S','S','E','D','\0',
     'H','A','S','_','H','H','\0',
     'H','U','S','H','\0',
+    'H','V','\0',
     'I','D','E','N','T','\0',
     'I','M','P','L','I','M','\0',
     'I','N','A','R','G','S','\0',
@@ -2266,6 +2297,7 @@ EXTCONST char PL_op_private_labels[] = {
     'I','N','C','R','\0',
     'I','N','P','L','A','C','E','\0',
     'I','N','T','\0',
+    'I','T','E','R','\0',
     'L','I','N','E','N','U','M','\0',
     'L','V','\0',
     'L','V','D','E','F','E','R','\0',
@@ -2294,6 +2326,7 @@ EXTCONST char PL_op_private_labels[] = {
     'S','T','A','T','E','\0',
     'S','T','R','I','C','T','\0',
     'S','U','B','\0',
+    'S','V','\0',
     'T','A','R','G','\0',
     'T','A','R','G','M','Y','\0',
     'U','N','I','\0',
@@ -2322,7 +2355,8 @@ EXTCONST I16 PL_op_private_bitfields[] = {
     0, 8, -1,
     0, 8, -1,
     0, 8, -1,
-    5, -1, 1, 124, 2, 131, 3, 138, -1,
+    5, -1, 1, 130, 2, 137, 3, 144, -1,
+    5, -1, 0, 481, 1, 26, 2, 250, 3, 83, -1,
 
 };
 
@@ -2710,6 +2744,10 @@ EXTCONST I16  PL_op_private_bitdef_ix[] = {
       -1, /* introcv */
       -1, /* clonecv */
      630, /* padrange */
+     632, /* refassign */
+     638, /* lvref */
+     644, /* lvrefslice */
+     645, /* lvavref */
 
 };
 
@@ -2729,71 +2767,71 @@ EXTCONST I16  PL_op_private_bitdef_ix[] = {
 
 EXTCONST U16  PL_op_private_bitdefs[] = {
     /* scalar        */ 0x0003,
-    /* pushmark      */ 0x25bc, 0x37b1,
+    /* pushmark      */ 0x281c, 0x3a11,
     /* wantarray     */ 0x00bd,
-    /* const         */ 0x0358, 0x1330, 0x386c, 0x3328, 0x2985,
-    /* gvsv          */ 0x25bc, 0x2ad1,
-    /* gv            */ 0x1235,
+    /* const         */ 0x03b8, 0x1490, 0x3acc, 0x3588, 0x2be5,
+    /* gvsv          */ 0x281c, 0x2d31,
+    /* gv            */ 0x12f5,
     /* gelem         */ 0x0067,
-    /* padsv         */ 0x25bc, 0x025a, 0x37b1,
-    /* padav         */ 0x25bc, 0x37b0, 0x26ac, 0x34a9,
-    /* padhv         */ 0x25bc, 0x0578, 0x04d4, 0x37b0, 0x26ac, 0x34a9,
-    /* pushre        */ 0x3279,
-    /* rv2gv         */ 0x25bc, 0x025a, 0x1430, 0x26ac, 0x28a8, 0x3864, 0x0003,
-    /* rv2sv         */ 0x25bc, 0x025a, 0x2ad0, 0x3864, 0x0003,
-    /* av2arylen     */ 0x26ac, 0x0003,
-    /* rv2cv         */ 0x281c, 0x0898, 0x0ad0, 0x028c, 0x39c8, 0x3864, 0x0003,
+    /* padsv         */ 0x281c, 0x025a, 0x3a11,
+    /* padav         */ 0x281c, 0x3a10, 0x290c, 0x3709,
+    /* padhv         */ 0x281c, 0x05d8, 0x0534, 0x3a10, 0x290c, 0x3709,
+    /* pushre        */ 0x34d9,
+    /* rv2gv         */ 0x281c, 0x025a, 0x1590, 0x290c, 0x2b08, 0x3ac4, 0x0003,
+    /* rv2sv         */ 0x281c, 0x025a, 0x2d30, 0x3ac4, 0x0003,
+    /* av2arylen     */ 0x290c, 0x0003,
+    /* rv2cv         */ 0x2a7c, 0x08f8, 0x0b90, 0x028c, 0x3c88, 0x3ac4, 0x0003,
     /* prototype     */ 0x0003,
     /* refgen        */ 0x0003,
     /* srefgen       */ 0x0003,
     /* ref           */ 0x0003,
     /* bless         */ 0x012f,
-    /* backtick      */ 0x2cbc, 0x2bd8, 0x2134, 0x2070, 0x0003,
+    /* backtick      */ 0x2f1c, 0x2e38, 0x22f4, 0x2230, 0x0003,
     /* glob          */ 0x012f,
     /* readline      */ 0x0003,
     /* regcmaybe     */ 0x0003,
     /* regcreset     */ 0x0003,
     /* regcomp       */ 0x0003,
-    /* match         */ 0x3278, 0x3a71,
-    /* qr            */ 0x3279,
-    /* subst         */ 0x3278, 0x3a71,
-    /* substcont     */ 0x3278, 0x0003,
-    /* trans         */ 0x0bdc, 0x1ab8, 0x07d4, 0x3a70, 0x35ec, 0x1de8, 
0x01e4, 0x0141,
-    /* transr        */ 0x0bdc, 0x1ab8, 0x07d4, 0x3a70, 0x35ec, 0x1de8, 
0x01e4, 0x0141,
-    /* sassign       */ 0x0a1c, 0x03f8, 0x0067,
-    /* aassign       */ 0x06f8, 0x26ac, 0x0067,
+    /* match         */ 0x34d8, 0x3d31,
+    /* qr            */ 0x34d9,
+    /* subst         */ 0x34d8, 0x3d31,
+    /* substcont     */ 0x34d8, 0x0003,
+    /* trans         */ 0x0c9c, 0x1c18, 0x0834, 0x3d30, 0x384c, 0x1fa8, 
0x01e4, 0x0141,
+    /* transr        */ 0x0c9c, 0x1c18, 0x0834, 0x3d30, 0x384c, 0x1fa8, 
0x01e4, 0x0141,
+    /* sassign       */ 0x0adc, 0x0458, 0x0067,
+    /* aassign       */ 0x0758, 0x290c, 0x0067,
     /* chop          */ 0x0003,
     /* schop         */ 0x0003,
-    /* chomp         */ 0x3a70, 0x0003,
-    /* schomp        */ 0x3a70, 0x0003,
**** PATCH TRUNCATED AT 2000 LINES -- 6196 NOT SHOWN ****

--
Perl5 Master Repository

Reply via email to