Skip to content

Commit f88445b

Browse files
committed
Fix GH-17654: Multiple classes using same trait causes function JIT crash
This test has two classes that use the same trait. In function JIT mode the same cache slot will be used. This causes problems because it is primed for the first class and then reused for the second class, resulting in an incorrect type check failure. The current check for a megamorphic trait call requires current_frame to not be NULL, but this is only set in tracing mode and not in function mode. This patch corrects the check. Closes GH-17660.
1 parent 76fccc2 commit f88445b

File tree

4 files changed

+48
-6
lines changed

4 files changed

+48
-6
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ PHP NEWS
1111
. Fixed bug GH-17618 (UnhandledMatchError does not take
1212
zend.exception_ignore_args=1 into account). (timwolla)
1313

14+
- Opcache:
15+
. Fixed bug GH-17654 (Multiple classes using same trait causes function
16+
JIT crash). (nielsdos)
17+
1418
- PHPDBG:
1519
. Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos)
1620
. Fix memory leak in phpdbg calling registered function. (nielsdos)

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9200,9 +9200,9 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
92009200
func = call_info->callee_func;
92019201
}
92029202
if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)
9203-
&& JIT_G(current_frame)
9204-
&& JIT_G(current_frame)->call
9205-
&& !JIT_G(current_frame)->call->func) {
9203+
&& (!JIT_G(current_frame) ||
9204+
!JIT_G(current_frame)->call ||
9205+
!JIT_G(current_frame)->call->func)) {
92069206
call_info = NULL; func = NULL; /* megamorphic call from trait */
92079207
}
92089208
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9931,9 +9931,9 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
99319931
func = call_info->callee_func;
99329932
}
99339933
if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)
9934-
&& JIT_G(current_frame)
9935-
&& JIT_G(current_frame)->call
9936-
&& !JIT_G(current_frame)->call->func) {
9934+
&& (!JIT_G(current_frame) ||
9935+
!JIT_G(current_frame)->call ||
9936+
!JIT_G(current_frame)->call->func)) {
99379937
call_info = NULL; func = NULL; /* megamorphic call from trait */
99389938
}
99399939
}

ext/opcache/tests/jit/gh17654.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
GH-17654 (Multiple classes using same trait causes function JIT crash)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit=1214
7+
opcache.jit_buffer_size=16M
8+
--FILE--
9+
<?php
10+
trait TestTrait {
11+
public function addUnit(string $x) {
12+
self::addRawUnit($this, $x);
13+
}
14+
15+
public function addRawUnit(self $data, string $x) {
16+
var_dump($x);
17+
}
18+
}
19+
20+
class Test {
21+
use TestTrait;
22+
}
23+
24+
class Test2 {
25+
use TestTrait;
26+
}
27+
28+
function main()
29+
{
30+
(new Test2)->addUnit("test2");
31+
(new Test)->addUnit("test");
32+
}
33+
34+
main();
35+
?>
36+
--EXPECT--
37+
string(5) "test2"
38+
string(4) "test"

0 commit comments

Comments
 (0)