diff --git a/perl.h b/perl.h index e31337a45130..0954a3984496 100644 --- a/perl.h +++ b/perl.h @@ -4107,6 +4107,9 @@ out there, Solaris being the most prominent. #endif #define UTF8fARG(u,l,p) (int)cBOOL(u), (UV)(l), (void*)(p) +/* For printing a PADNAME. Ideally these would have been named + * PADNAMEf and PADNAMEfARG + */ #define PNf UTF8f #define PNfARG(pn) (int)1, (UV)PadnameLEN(pn), (void *)PadnamePV(pn) diff --git a/pod/perldiag.pod b/pod/perldiag.pod index cdd940729678..838133ff5101 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -8328,6 +8328,15 @@ anonymous, using the C syntax. When inner anonymous subs that reference variables in outer subroutines are created, they are automatically rebound to the current values of such variables. +=item Variable "%s" will not stay shared after refalias + +(W closure) A refalias operation has been performed on a variable that is +captured by one or more closures, and thus is shared between them. As a +result of the way it is currently implemented, the variable in the scope +that performed has now become disconnected from those in other scopes, and +now operates independently. Updates to this variable will not be reflected +in the others, or vice versa. + =item vector argument not supported with alpha versions (S printf) The %vd (s)printf format does not support version objects diff --git a/pp.c b/pp.c index 5d3ecdfc45a6..8095336f8a51 100644 --- a/pp.c +++ b/pp.c @@ -7624,6 +7624,12 @@ PP(pp_refassign) case 0: { SV * const old = PAD_SV(ARGTARG); + if(SvREFCNT(old) > 1) { + PADNAME *pn = PadlistNAMESARRAY(CvPADLIST(find_runcv(NULL)))[ARGTARG]; + warner(packWARN(WARN_CLOSURE), + "Variable \"%" PNf "\" will not stay shared after refalias", + PNfARG(pn)); + } PAD_SETSV(ARGTARG, SvREFCNT_inc_NN(SvRV(sv))); SvREFCNT_dec(old); if ((PL_op->op_private & (OPpLVAL_INTRO|OPpPAD_STATE)) diff --git a/t/op/lvref.t b/t/op/lvref.t index 1435aa9f5125..1c52dfe9acbe 100644 --- a/t/op/lvref.t +++ b/t/op/lvref.t @@ -5,7 +5,7 @@ BEGIN { set_up_inc("../lib"); } -plan 203; +plan 204; eval '\$x = \$y'; like $@, qr/^Experimental aliasing via reference not enabled/, @@ -626,6 +626,9 @@ like $@, # Miscellaneous { + my $warnings = ""; + local $SIG{__WARN__} = sub { $warnings .= $_[0]; }; + local $::TODO = ' '; my($x,$y); sub { @@ -635,6 +638,10 @@ like $@, is \$x, \$y, 'lexical alias affects outer closure'; }->(); is \$x, \$y, 'lexical alias affects outer sub where vars are declared'; + + undef $::TODO; + like $warnings, qr/^Variable "\$x" will not stay shared after refalias /, + 'warning emitted by refalias on closure shared variable'; } { # PADSTALE has a double meaning