summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-04-07 17:34:53 +0300
committerDmitry Stogov <dmitry@zend.com>2016-04-07 17:34:53 +0300
commit3444c1ae2400b279b936c4ca04cb84dfdfb57bbf (patch)
treea63676497e4c163bb917a183780180e743a1acd2 /Zend/zend_compile.c
parent708d030b694f89a001c5f5ed6e3af25e7097f483 (diff)
downloadphp-git-3444c1ae2400b279b936c4ca04cb84dfdfb57bbf.tar.gz
Use return type hints for type inference and eliminate useless VERIFY_RETRUN_TYPE opcodes.
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r--Zend/zend_compile.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 5f3114d10e..da2c83c55e 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2265,12 +2265,30 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */
static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) /* {{{ */
{
/* `return ...;` is illegal in a void function (but `return;` isn't) */
- if (expr && return_info->type_hint == IS_VOID) {
- zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value");
+ if (return_info->type_hint == IS_VOID) {
+ if (expr) {
+ zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value");
+ }
+ /* we don't need run-time check */
+ return;
}
if (return_info->type_hint != IS_UNDEF) {
- zend_op *opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL);
+ zend_op *opline;
+
+ if (expr && expr->op_type == IS_CONST) {
+ if ((return_info->type_hint == Z_TYPE(expr->u.constant))
+ ||((return_info->type_hint == _IS_BOOL)
+ && (Z_TYPE(expr->u.constant) == IS_FALSE
+ || Z_TYPE(expr->u.constant) == IS_TRUE))
+ || (return_info->allow_null
+ && Z_TYPE(expr->u.constant) == IS_NULL)) {
+ /* we don't need run-time check */
+ return;
+ }
+ }
+
+ opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL);
if (expr && expr->op_type == IS_CONST) {
opline->result_type = expr->op_type = IS_TMP_VAR;
opline->result.var = expr->u.op.var = get_temporary_variable(CG(active_op_array));