Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:26402 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 62191 invoked by uid 1010); 7 Nov 2006 11:07:56 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 62176 invoked from network); 7 Nov 2006 11:07:56 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Nov 2006 11:07:56 -0000 X-Host-Fingerprint: 80.123.98.46 unknown Received: from [80.123.98.46] ([80.123.98.46:12918] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A9/70-58090-A0960554 for ; Tue, 07 Nov 2006 06:07:55 -0500 To: internals@lists.php.net,Dmitry Stogov Message-ID: <4550691D.2080302@php.net> Date: Tue, 07 Nov 2006 12:08:13 +0100 User-Agent: Thunderbird 1.5.0.7 (X11/20060918) MIME-Version: 1.0 References: <018201c7025a$d8042150$0201a8c0@pc1> In-Reply-To: <018201c7025a$d8042150$0201a8c0@pc1> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Posted-By: 80.123.98.46 Subject: Re: [PATCH] =& doesn't remove "old" references like unset() From: mike@php.net (Michael Wallner) Matt Wilmas wrote: > Hi (Dmitry?), > > See Bug #33282 -- I saw it in the Bug Summary; don't know if there are other > related ones... Same applies to foreach ($arr ... &$v) which is where I > noticed it last week with var_dump($arr). All elements that WERE referenced > but aren't anymore still have is_ref=1 (when refcount=1). Only the last > referenced element should be a reference (unless the others were to begin > with). unset()'ing the reference variable removes the reference from the > last element. Example: > > $a = array(1, 2, 3); > $r = &$a[0]; > $r = &$a[1]; > $r = &$a[2]; > var_dump($a); > > array(3) { > [0]=> > &int(1) > [1]=> > &int(2) > [2]=> > &int(3) // unset($r) will take care of this one > } > > The reference (&) should no longer be on the first 2 elements, right? > Setting is_ref=0 when refcount=1 in zend_assign_to_variable_reference() > fixes it. I assume it won't cause other problems since the same thing is > done in zval_ptr_dtor(). :-) > This looks like it may actually fix a lot of previously bogus'ed bug reports? > > ------------------------------------------------------------------------ > > Index: zend_execute.c > =================================================================== > RCS file: /repository/ZendEngine2/zend_execute.c,v > retrieving revision 1.752 > diff -u -r1.752 zend_execute.c > --- zend_execute.c 2 Oct 2006 11:05:02 -0000 1.752 > +++ zend_execute.c 7 Nov 2006 05:24:38 -0000 > @@ -438,6 +438,8 @@ > if (variable_ptr->refcount==0) { > zendi_zval_dtor(*variable_ptr); > FREE_ZVAL(variable_ptr); > + } else if (variable_ptr->refcount == 1) { > + variable_ptr->is_ref = 0; > } > } else if (!variable_ptr->is_ref) { > if (variable_ptr_ptr == value_ptr_ptr) { > > > ------------------------------------------------------------------------ > > Index: zend_execute.c > =================================================================== > RCS file: /repository/ZendEngine2/zend_execute.c,v > retrieving revision 1.716.2.12.2.12 > diff -u -r1.716.2.12.2.12 zend_execute.c > --- zend_execute.c 2 Oct 2006 11:09:52 -0000 1.716.2.12.2.12 > +++ zend_execute.c 7 Nov 2006 05:24:40 -0000 > @@ -415,6 +415,8 @@ > if (variable_ptr->refcount==0) { > zendi_zval_dtor(*variable_ptr); > FREE_ZVAL(variable_ptr); > + } else if (variable_ptr->refcount == 1) { > + variable_ptr->is_ref = 0; > } > } else if (!variable_ptr->is_ref) { > if (variable_ptr_ptr == value_ptr_ptr) { -- Michael