summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPGRADING2
-rw-r--r--Zend/tests/errmsg_041.phpt11
-rw-r--r--Zend/tests/instanceof_const.phpt10
-rw-r--r--Zend/zend_compile.c6
-rw-r--r--ext/opcache/Optimizer/sccp.c17
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c1
6 files changed, 33 insertions, 14 deletions
diff --git a/UPGRADING b/UPGRADING
index 3565c28a96..7413f7b2d1 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -58,6 +58,8 @@ Core:
. Array destructuring now supports reference assignments using the syntax
[&$a, [$b, &$c]] = $d. The same is also supported for list().
(RFC: https://wiki.php.net/rfc/list_reference_assignment)
+ . instancof now allows literal as the first operand,
+ in this case the result always be FALSE.
BCMath:
. bcscale() can now also be used as getter to retrieve the current scale in use.
diff --git a/Zend/tests/errmsg_041.phpt b/Zend/tests/errmsg_041.phpt
deleted file mode 100644
index bfcafd261d..0000000000
--- a/Zend/tests/errmsg_041.phpt
+++ /dev/null
@@ -1,11 +0,0 @@
---TEST--
-errmsg: instanceof expects an object instance, constant given
---FILE--
-<?php
-
-var_dump("abc" instanceof stdclass);
-
-echo "Done\n";
-?>
---EXPECTF--
-Fatal error: instanceof expects an object instance, constant given in %s on line %d
diff --git a/Zend/tests/instanceof_const.phpt b/Zend/tests/instanceof_const.phpt
new file mode 100644
index 0000000000..f662d91603
--- /dev/null
+++ b/Zend/tests/instanceof_const.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Instanceof on literals returns false
+--FILE--
+<?php
+
+var_dump("abc" instanceof stdclass);
+
+?>
+--EXPECT--
+bool(false)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 8d690153e8..68cd87d40b 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7468,8 +7468,10 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&obj_node, obj_ast);
if (obj_node.op_type == IS_CONST) {
- zend_error_noreturn(E_COMPILE_ERROR,
- "instanceof expects an object instance, constant given");
+ zend_do_free(&obj_node);
+ result->op_type = IS_CONST;
+ ZVAL_FALSE(&result->u.constant);
+ return;
}
zend_compile_class_ref_ex(&class_node, class_ast,
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index 0e65ac8b8f..25b51b687a 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -242,7 +242,6 @@ static zend_bool can_replace_op1(
case ZEND_MAKE_REF:
case ZEND_UNSET_CV:
case ZEND_ISSET_ISEMPTY_CV:
- case ZEND_INSTANCEOF:
return 0;
case ZEND_INIT_ARRAY:
case ZEND_ADD_ARRAY_ELEMENT:
@@ -299,6 +298,22 @@ static zend_bool try_replace_op1(
opline->op1.constant = zend_optimizer_add_literal(ctx->scdf.op_array, &zv);
opline->op1_type = IS_CONST;
return 1;
+ case ZEND_INSTANCEOF:
+ zval_ptr_dtor_nogc(&zv);
+ ZVAL_FALSE(&zv);
+ opline->opcode = ZEND_QM_ASSIGN;
+ opline->op1_type = IS_CONST;
+ opline->op1.constant = zend_optimizer_add_literal(ctx->scdf.op_array, &zv);
+ opline->op2_type = IS_UNUSED;
+ if (ssa_op->op2_use >= 0) {
+ ZEND_ASSERT(ssa_op->op2_def == -1);
+ zend_ssa_unlink_use_chain(ctx->scdf.ssa, ssa_op - ctx->scdf.ssa->ops, ssa_op->op2_use);
+ ssa_op->op2_use = -1;
+ ssa_op->op2_use_chain = -1;
+ }
+ return 1;
+ default:
+ break;
}
zval_ptr_dtor_nogc(&zv);
}
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 37357f3c31..97be113f47 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -272,6 +272,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_FETCH_LIST_W:
case ZEND_ASSIGN_DIM:
case ZEND_RETURN_BY_REF:
+ case ZEND_INSTANCEOF:
return 0;
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_CATCH: