mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-20377: emit assignment for all final promoted properties (#20378)
Previously, the assignment op line was only emitted when one of the other flags allowed for promoted properties (visibility, set visibility, or readonly) was also used, or when the property had hooks. The property was still added to the class, but the magical assignment `$this->prop = $prop` was missing. Add that assignment even when no visibility is explicitly specified, and a test to confirm the fix.
This commit is contained in:
2
NEWS
2
NEWS
@@ -8,6 +8,8 @@ PHP NEWS
|
||||
(ilutov)
|
||||
. Fixed bug GH-20194 (null offset deprecation not emitted for writes).
|
||||
(Girgias)
|
||||
. Fixed bug GH-GH-20377 (final promoted properties without explicit visibility
|
||||
not automatically assigned). (DanielEScherzer)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug GH-20012 (heap buffer overflow in jit). (Arnaud)
|
||||
|
||||
23
Zend/tests/ctor_promotion/ctor_promotion_final.phpt
Normal file
23
Zend/tests/ctor_promotion/ctor_promotion_final.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
GH-20377: Constructor promotion with a final property without visibility set
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Demo {
|
||||
public function __construct(
|
||||
final string $foo,
|
||||
final public string $bar,
|
||||
) {}
|
||||
}
|
||||
|
||||
$d = new Demo("first", "second");
|
||||
var_dump($d);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(Demo)#%d (2) {
|
||||
["foo"]=>
|
||||
string(5) "first"
|
||||
["bar"]=>
|
||||
string(6) "second"
|
||||
}
|
||||
@@ -7770,6 +7770,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t promotion_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL;
|
||||
for (i = 0; i < list->children; ++i) {
|
||||
zend_ast *param_ast = list->child[i];
|
||||
zend_ast *type_ast = param_ast->child[0];
|
||||
@@ -7781,7 +7782,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
|
||||
zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast));
|
||||
bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
|
||||
bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0;
|
||||
uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL);
|
||||
uint32_t property_flags = param_ast->attr & promotion_flags;
|
||||
bool is_promoted = property_flags || hooks_ast;
|
||||
|
||||
CG(zend_lineno) = param_ast->lineno;
|
||||
@@ -8008,7 +8009,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
|
||||
zend_ast *param_ast = list->child[i];
|
||||
zend_ast *hooks_ast = param_ast->child[5];
|
||||
bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
|
||||
uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY);
|
||||
uint32_t flags = param_ast->attr & promotion_flags;
|
||||
bool is_promoted = flags || hooks_ast;
|
||||
if (!is_promoted) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user