Skip to content

Commit 5dcd4f6

Browse files
committed
Merge branch 'PHP-8.6'
* PHP-8.6: Fix block pass dropping ZEND_FAST_CALL OP2 definition
2 parents 047450e + 2b6a301 commit 5dcd4f6

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎Zend/Optimizer/block_pass.c‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,18 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
352352
}
353353
break;
354354

355+
case ZEND_FAST_CALL:
356+
if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
357+
/* OP2 holds the pending return value. A TMP normally has a single
358+
* consumer, but FAST_CALL reads does not consume it:
359+
* the RETURN behind it is the consumer, and
360+
* zend_dispatch_try_catch_finally_helper() destroys the value
361+
* through OP2 if the finally block throws. Propagating the source
362+
* into the RETURN therefore must not remove it. */
363+
Tsource[VAR_NUM(opline->op2.var)] = NULL;
364+
}
365+
break;
366+
355367
case ZEND_SWITCH_LONG:
356368
case ZEND_SWITCH_STRING:
357369
case ZEND_MATCH:
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Block pass must not remove the source of the ZEND_FAST_CALL OP2 return value
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
--FILE--
9+
<?php
10+
function test_scalar() {
11+
$x = 1;
12+
try {
13+
try {
14+
return true ? 1.5 : 2.5;
15+
} finally {
16+
undef_fn();
17+
}
18+
} catch (Throwable $e) {
19+
echo $e::class, ': ', $e->getMessage(), "\n";
20+
}
21+
return "fallback";
22+
}
23+
24+
function test_refcounted() {
25+
$x = 1;
26+
try {
27+
try {
28+
return true ? "returned" : "other";
29+
} finally {
30+
undef_fn();
31+
}
32+
} catch (Throwable $e) {
33+
echo $e::class, ': ', $e->getMessage(), "\n";
34+
}
35+
return "fallback";
36+
}
37+
38+
var_dump(test_scalar());
39+
var_dump(test_refcounted());
40+
?>
41+
--EXPECT--
42+
Error: Call to undefined function undef_fn()
43+
string(8) "fallback"
44+
Error: Call to undefined function undef_fn()
45+
string(8) "fallback"

0 commit comments

Comments
 (0)