Hi: I believe there's a missing refcount increment causing this bug, and I think I may have uncovered some evidence that could get us closer to a fix. I've added opcode dumps to zend_execute.c with a well-placed perl command, so as to see the instructions as they're executed.
All of the following has been performed against a clean snapshot of PHP4 CVS HEAD. Given the following script, containing one class with two methods differing only by a silence operator: <?php class foo { function &method1() { return $this->foo; } function &method2() { return @$this->foo; } } $i = new foo(); $i->method1(); echo "\n"; $i->method2(); ?> The following opcodes pass throuch the main switch() in execute(), in this order: ZEND_NOP ZEND_NEW ZEND_JMP_NO_CTOR ZEND_FETCH_W ZEND_FETCH_LOCAL ZEND_ASSIGN ZEND_FETCH_W ZEND_FETCH_LOCAL ZEND_INIT_FCALL_BY_NAME ZEND_DO_FCALL_BY_NAME ZEND_FETCH_W ZEND_FETCH_LOCAL ZEND_FETCH_OBJ_W ZEND_RETURN ZEND_ECHO ZEND_FETCH_W ZEND_FETCH_LOCAL ZEND_INIT_FCALL_BY_NAME ZEND_DO_FCALL_BY_NAME ZEND_BEGIN_SILENCE ZEND_FETCH_R ZEND_FETCH_LOCAL ZEND_FETCH_OBJ_R ZEND_END_SILENCE ZEND_RETURN ZEND_RETURN Here, we see the object property which will eventually become the return value of method1() being fetched by the engine with ZEND_FETCH_OBJ_W, which triggers a zend_fetch_property_address(..., BP_VAR_W) from zend_execute.c:1354, eventually bumping the reference count in zend_fetch_property_address_inner: case BP_VAR_W: { zval *new_zval = &EG(uninitialized_zval); new_zval->refcount++; zend_hash_update(ht, prop_ptr->value.str.val, ...snip...); } However, it seems the addition of the silence operator (which wouldn't have an effect on the read/write status of the fetch or the refcount, I wouldn't think) makes the engine fetch with ZEND_FETCH_OBJ_R; eventually triggering another branch of the switch in zend_get_property_address_inner: case BP_VAR_R: zend_error(E_NOTICE,"Undefined property: %s", prop_ptr->value.str.val); /* break missing intentionally */ case BP_VAR_IS: retval = &EG(uninitialized_zval_ptr); break; Which omits the increment of the reference count. There is a call to AI_USE_PTR() on the read path that isn't on the write path, but that looks like it doesn't touch the refcount of anything. So, anyway. I may be completely off in left-field here; apologies if you've made it this far and none of this represents any sort of sane thinking. :) But, is it possible that the silence operator, when applied to a fetch of an object property that is returned by reference, is being miscompiled as ZEND_FETCH_OBJ_R rather than ZEND_FETCH_OBJ_W? (Be gentle with replies; this is the first time I've ever really touched the Zend Engine's guts. I've appended this to the entry on bugs.php.net as well.) Thanks in advance, - Dave [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php