summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
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));