Skip to content

Commit 1b33da5

Browse files
committed
Don't replace values in unreachable code in sccp
While technically legal, this may cause unexpected situations (in this example, setting an FE_FREE operand to constant null) and is suboptimal anyway. It's better to preserve the vacuous type and drop it later (though we currently don't implement this).
1 parent b4d7387 commit 1b33da5

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,6 +2139,12 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
21392139
return NULL;
21402140
}
21412141

2142+
if (!(info->type & MAY_BE_ANY)) {
2143+
/* This code must be unreachable. We could replace operands with NULL, but this doesn't
2144+
* really make things better. It would be better to later remove this code entirely. */
2145+
return NULL;
2146+
}
2147+
21422148
if (!(info->type & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_NULL))) {
21432149
ZVAL_NULL(tmp);
21442150
return tmp;

ext/opcache/tests/opt/sccp_022.phpt

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,23 @@ function foo(int $x) {
1717
$a->foo = 5;
1818
echo $a[1];
1919
}
20+
function bar() {
21+
foreach ($a as $v) {
22+
foreach ($v as $v2) {}
23+
}
24+
}
2025
?>
2126
--EXPECTF--
2227
$_main:
2328
; (lines=1, args=0, vars=0, tmps=0)
2429
; (after optimizer)
25-
; %ssccp_022.php:1-10
30+
; %s
2631
0000 RETURN int(1)
2732

2833
foo:
29-
; (lines=10, args=1, vars=2, tmps=1)
34+
; (lines=11, args=1, vars=2, tmps=1)
3035
; (after optimizer)
31-
; %ssccp_022.php:2-8
36+
; %s
3237
0000 CV0($x) = RECV 1
3338
0001 ASSIGN_DIM CV1($a) int(0)
3439
0002 OP_DATA CV0($x)
@@ -37,5 +42,23 @@ foo:
3742
0005 ECHO string("5")
3843
0006 ASSIGN_OBJ CV1($a) string("foo")
3944
0007 OP_DATA int(5)
40-
0008 T2 = FETCH_DIM_R null int(1)
41-
0009 RETURN null
45+
0008 T2 = FETCH_DIM_R CV1($a) int(1)
46+
0009 ECHO T2
47+
0010 RETURN null
48+
49+
bar:
50+
; (lines=9, args=0, vars=3, tmps=2)
51+
; (after optimizer)
52+
; %s
53+
0000 V3 = FE_RESET_R CV0($a) 0007
54+
0001 FE_FETCH_R V3 CV1($v) 0007
55+
0002 V4 = FE_RESET_R CV1($v) 0005
56+
0003 FE_FETCH_R V4 CV2($v2) 0005
57+
0004 JMP 0003
58+
0005 FE_FREE V4
59+
0006 JMP 0001
60+
0007 FE_FREE V3
61+
0008 RETURN null
62+
LIVE RANGES:
63+
3: 0001 - 0007 (loop)
64+
4: 0003 - 0005 (loop)

0 commit comments

Comments
 (0)