From 7e482323fb2aaa4e52b80f3c50b716c8b6ef41c8 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Tue, 10 Jan 2012 08:55:08 -0800 Subject: [perl #35865, #43011] FETCH after autovivifying MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After autovivification, perl should not assume that the value it has assigned to a magical scalar is the one that would have been returned. The result of this assumption is that any tie class that copies things assigned to it will cause autovivification to assign to a temporary aggregate without warning, in cases like this: $tied{nonexistent}{foo} = 7; The hash implicitly assigned to $tied{nonexistent} ends up being freed after the =7 assignment. This commit changes autovivification to do FETCH immediately after doing STORE. This required changing some recently-added tests in gmagic.t. Without this change, you end up with horrific workarounds (using B.pm to get the reference count), like the one in JE::Object (which I’m pasting here, in case it has changed by the time you read this): sub STORE { my($self, $key, $val) = @_; my $global = $self->global; if(ref $val eq 'HASH' && !blessed $val && !%$val && svref_2object($val)->REFCNT == 2) { $val = tie %$val, __PACKAGE__, __PACKAGE__->new( $global); } elsif (ref $val eq 'ARRAY' && !blessed $val && !@$val && svref_2object($val)->REFCNT == 2) { require JE::Object::Array; $val = tie @$val, 'JE::Object::Array', JE::Object::Array->new($global); } $self->prop($key => $global->upgrade($val)) } --- pp_hot.c | 1 + 1 file changed, 1 insertion(+) (limited to 'pp_hot.c') diff --git a/pp_hot.c b/pp_hot.c index ff834a924e..a66a690608 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -2898,6 +2898,7 @@ Perl_vivify_ref(pTHX_ SV *sv, U32 to_what) } SvROK_on(sv); SvSETMAGIC(sv); + SvGETMAGIC(sv); } if (SvGMAGICAL(sv)) { /* copy the sv without magic to prevent magic from being -- cgit v1.2.1