Skip to content

Commit ba8bcf3

Browse files
committed
Drop incorrect cache_slot optimization for typed properties
For a particular assignment, a non-coerced constant assignment value will remain valid. However, opcache merges cache slots for all identical property references, which means that this optimization also disables property type checks for all other operands on the property that occur in the same functions. This could be addressed by blocking cache slot merging in opcache, but I prefer dropping it entirely instead. It does not seem important enough to warrant doing that.
1 parent f40dced commit ba8bcf3

File tree

3 files changed

+30
-407
lines changed

3 files changed

+30
-407
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Demonstrate that cache_slot optimization is illegal due to cache_slot merging
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public int $prop;
8+
9+
public function method() {
10+
// Opcache merges cache slots for both assignments.
11+
$this->prop = 1;
12+
try {
13+
$this->prop = "foobar";
14+
} catch (TypeError $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
var_dump($this->prop);
18+
}
19+
}
20+
21+
$test = new Test;
22+
$test->method();
23+
$test->method();
24+
25+
?>
26+
--EXPECT--
27+
Typed property Test::$prop must be int, string used
28+
int(1)
29+
Typed property Test::$prop must be int, string used
30+
int(1)

Zend/zend_vm_def.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,18 +2480,7 @@ ZEND_VM_C_LABEL(assign_object):
24802480
zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
24812481

24822482
if (UNEXPECTED(prop_info != NULL)) {
2483-
zend_uchar orig_type = IS_UNDEF;
2484-
2485-
if (OP_DATA_TYPE == IS_CONST) {
2486-
orig_type = Z_TYPE_P(value);
2487-
}
2488-
24892483
value = zend_assign_to_typed_prop(prop_info, property_val, value EXECUTE_DATA_CC);
2490-
2491-
/* will remain valid, thus no need to check prop_info in future here */
2492-
if (OP_DATA_TYPE == IS_CONST && Z_TYPE_P(value) == orig_type) {
2493-
CACHE_PTR_EX(cache_slot + 2, NULL);
2494-
}
24952484
ZEND_VM_C_GOTO(free_and_exit_assign_obj);
24962485
} else {
24972486
ZEND_VM_C_LABEL(fast_assign_obj):

0 commit comments

Comments
 (0)