diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 047427072388..8d01ac050cf6 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5264,6 +5264,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op * and the value already has this type: the old value has no destructor. * If the property holds a reference, all its type sources accept this type because they accept the current value. */ if ((prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) + || prop_info->hooks || ZEND_TYPE_IS_COMPLEX(prop_info->type) || (type_mask & ~(MAY_BE_NULL|MAY_BE_BOOL|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING)) /* single type, this excludes bool too as a reference can exist to true or false standalone types. */ diff --git a/ext/opcache/tests/jit/assign_obj_007.phpt b/ext/opcache/tests/jit/assign_obj_007.phpt new file mode 100644 index 000000000000..3843b07e8593 --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_007.phpt @@ -0,0 +1,44 @@ +--TEST-- +JIT ASSIGN_OBJ: exception thrown by a set hook on a typed property +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.jit=tracing +opcache.jit_hot_loop=1 +opcache.jit_hot_func=1 +opcache.jit_hot_return=1 +opcache.jit_hot_side_exit=1 +--FILE-- +test = $v; + } + } +} + +function test() { + $foo = new Foo; + for ($i = 0; $i < 10; $i++) { + $foo->test = $i; + echo $i, PHP_EOL; + } +} + +try { + test(); +} catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +0 +1 +2 +Exception: hook threw