Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:18379 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 28402 invoked by uid 1010); 24 Aug 2005 21:45:49 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 28387 invoked from network); 24 Aug 2005 21:45:49 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Aug 2005 21:45:49 -0000 X-Host-Fingerprint: 204.11.219.139 lerdorf.com Linux 2.4/2.6 Received: from ([204.11.219.139:39658] helo=colo.lerdorf.com) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id CE/CD-28235-C8AEC034 for ; Wed, 24 Aug 2005 17:45:49 -0400 Received: from [207.126.233.18] (rasmus2.corp.yahoo.com [207.126.233.18]) (authenticated bits=0) by colo.lerdorf.com (8.13.4/8.13.4/Debian-3) with ESMTP id j7OLjh0W020755 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 24 Aug 2005 14:45:44 -0700 Message-ID: <430CEA87.7040805@lerdorf.com> Date: Wed, 24 Aug 2005 14:45:43 -0700 User-Agent: Mozilla Thunderbird 1.0.6 (Macintosh/20050716) X-Accept-Language: en-us, en MIME-Version: 1.0 To: internals CC: Stanislav Malyshev X-Enigmail-Version: 0.92.0.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Schroedinger Objects From: rasmus@lerdorf.com (Rasmus Lerdorf) As per bug #34199 and as Rob points out, if($obj) and if(!$obj) are handled by different opcodes and these two opcodes are inconsistent in whether they call an object's cast_object handler. if($obj) results in a ZEND_JMPZ_SPEC_CV_HANDLER which calls i_zend_is_true() which always return true for objects, no matter what (ignore compatibility mode here) because of this code in zend_execute.h: case IS_OBJECT: if(IS_ZEND_STD_OBJECT(*op)) { TSRMLS_FETCH(); if(EG(ze1_compatibility_mode)) { result = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0); } else { result = 1; } } else { result = 1; } break; if(!$obj) results in a which calls convert_to_boolean() which in turn calls convert_object_to_type() which has: if (Z_OBJ_HT_P(op)->cast_object) { if (Z_OBJ_HT_P(op)->cast_object(op, op, ctype, 1 TSRMLS_CC) == SUCCESS) { op->type = ctype; } This means that any object which actually implements a cast_object handler that returns false under some condition will be broken. The simple example is: $a = simplexml_load_string(''); if($a && !$a) echo "BUG!"; I think we need to fix i_zend_is_true's IS_OBJECT case to check to see if the object has a cast_object handler and call it or just call convert_to_boolean() there. Or we need to clean this up and not have such different codepaths for these two cases. -Rasmus