Skip to content

Commit

Permalink
Fixed type inference that may cause JIT failure
Browse files Browse the repository at this point in the history
PHP allows to override a method that returns non-reference with a method
that returns a reference. This mean that we cannot use prototypes to
predict return types of a child functions.
  • Loading branch information
dstogov committed Oct 6, 2021
1 parent 5ed654e commit 0b5d62e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Zend/Optimizer/zend_func_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ ZEND_API uint32_t zend_get_func_info(
if (!ret) {
ret = zend_get_return_info_from_signature_only(
callee_func, /* TODO: script */ NULL, ce, ce_is_instanceof, /* use_tentative_return_info */ !call_info->is_prototype);
/* It's allowed to override a method that return non-reference with a method that returns a reference */
if (call_info->is_prototype && (ret & ~MAY_BE_REF)) {
ret |= MAY_BE_REF;
}
}
}
return ret;
Expand Down
28 changes: 28 additions & 0 deletions ext/opcache/tests/jit/ret_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
JIT RET: 004 Return a reference when it's not expected
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit_buffer_size=32M
--FILE--
<?php
class A {
function foo() {
}
function bar() {
$x = $this->foo();
var_dump(str_repeat($x,5));
}
}
class B extends A {
public $prop = "x";
function &foo() {
return $this->prop;
}
}
$b = new B;
$b->bar();
?>
--EXPECT--
string(5) "xxxxx"

0 comments on commit 0b5d62e

Please sign in to comment.