Skip to content

Commit 0b5d62e

Browse files
committed
Fixed type inference that may cause JIT failure
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.
1 parent 5ed654e commit 0b5d62e

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

Zend/Optimizer/zend_func_info.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ ZEND_API uint32_t zend_get_func_info(
180180
if (!ret) {
181181
ret = zend_get_return_info_from_signature_only(
182182
callee_func, /* TODO: script */ NULL, ce, ce_is_instanceof, /* use_tentative_return_info */ !call_info->is_prototype);
183+
/* It's allowed to override a method that return non-reference with a method that returns a reference */
184+
if (call_info->is_prototype && (ret & ~MAY_BE_REF)) {
185+
ret |= MAY_BE_REF;
186+
}
183187
}
184188
}
185189
return ret;

ext/opcache/tests/jit/ret_004.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
JIT RET: 004 Return a reference when it's not expected
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=32M
8+
--FILE--
9+
<?php
10+
class A {
11+
function foo() {
12+
}
13+
function bar() {
14+
$x = $this->foo();
15+
var_dump(str_repeat($x,5));
16+
}
17+
}
18+
class B extends A {
19+
public $prop = "x";
20+
function &foo() {
21+
return $this->prop;
22+
}
23+
}
24+
$b = new B;
25+
$b->bar();
26+
?>
27+
--EXPECT--
28+
string(5) "xxxxx"

0 commit comments

Comments
 (0)