Skip to content

Commit

Permalink
Fix return type verification with undef var
Browse files Browse the repository at this point in the history
This was loading EG(uninitialized_value) into r0 rather than
FCARG1a.

However, if we fix this issue an existing test fails because
the undef var warning promoted to exception is not caught early
enough, so we need to explicitly check for the exception before
performing the type check.
  • Loading branch information
nikic committed Oct 5, 2021
1 parent 22ef1fb commit f890c9c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
16 changes: 10 additions & 6 deletions ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -14854,29 +14854,33 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op
needs_slow_check = 0;
} else if (is_power_of_two(type_mask)) {
uint32_t type_code = concrete_type(type_mask);
| IF_NOT_ZVAL_TYPE op1_addr, type_code, >7
| IF_NOT_ZVAL_TYPE op1_addr, type_code, >6
} else {
| mov edx, 1
| GET_ZVAL_TYPE cl, op1_addr
| shl edx, cl
| test edx, type_mask
| je >7
| je >6
}
}
if (needs_slow_check) {
if (slow_check_in_cold) {
|.cold_code
|7:
|6:
}
| SET_EX_OPLINE opline, r1
if (op1_info & MAY_BE_UNDEF) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >8
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >7
| mov FCARG1a, opline->op1.var
| EXT_CALL zend_jit_undefined_op_helper, FCARG2a
| LOAD_ADDR_ZTS r0, executor_globals, uninitialized_zval
| test r0, r0
| jz ->exception_handler
| LOAD_ADDR_ZTS FCARG1a, executor_globals, uninitialized_zval
| jmp >8
}
|8:
|7:
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
|8:
| mov FCARG2a, EX->func
|.if X64
| LOAD_ADDR CARG3, (ptrdiff_t)arg_info
Expand Down
24 changes: 24 additions & 0 deletions ext/opcache/tests/jit/verify_return_undef.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
VERIFY_RETURN with undef var
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit_buffer_size=1M
--FILE--
<?php

function test(): int {
return $undef;
}

try {
test();
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECTF--
Warning: Undefined variable $undef in %s on line %d
test(): Return value must be of type int, null returned

0 comments on commit f890c9c

Please sign in to comment.