uint32_t tmp = 0;
uint32_t t1_type = (t1 & MAY_BE_ANY) | (t1 & MAY_BE_UNDEF ? MAY_BE_NULL : 0);
uint32_t t2_type = (t2 & MAY_BE_ANY) | (t2 & MAY_BE_UNDEF ? MAY_BE_NULL : 0);
+
+ /* Handle potentially overloaded operators.
+ * This could be made more precise by checking the class type, if known. */
+ if ((t1_type & MAY_BE_OBJECT) || (t2_type & MAY_BE_OBJECT)) {
+ /* This is somewhat GMP specific. */
+ tmp |= MAY_BE_OBJECT | MAY_BE_FALSE | MAY_BE_RC1;
+ }
+
switch (opcode) {
case ZEND_ADD:
if (t1_type == MAY_BE_LONG && t2_type == MAY_BE_LONG) {
* handling */
break;
case ZEND_MOD:
- tmp = MAY_BE_LONG;
+ tmp |= MAY_BE_LONG;
/* Division by zero results in an exception, so it doesn't need any special handling */
break;
case ZEND_BW_OR:
break;
case ZEND_SL:
case ZEND_SR:
- tmp = MAY_BE_LONG;
+ tmp |= MAY_BE_LONG;
break;
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
if (t1 & (MAY_BE_ANY-MAY_BE_STRING)) {
tmp |= MAY_BE_LONG;
}
+ if (t1 & MAY_BE_OBJECT) {
+ /* Potentially overloaded operator. */
+ tmp |= MAY_BE_OBJECT | MAY_BE_RC1;
+ }
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
break;
case ZEND_BEGIN_SILENCE: