Skip to content

Commit 8d4a949

Browse files
committed
Merge branch 'master' into levim/zend_hash_find_known_hash
2 parents dd36323 + 576655e commit 8d4a949

File tree

158 files changed

+2251
-1056
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+2251
-1056
lines changed

NEWS

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3-
?? ??? ????, PHP 8.1.0beta1
3+
?? ??? ????, PHP 8.1.0beta2
4+
5+
- Opcache:
6+
. Fixed Bug #81255 (Memory leak in PHPUnit with functional JIT)
7+
8+
22 Jul 2021, PHP 8.1.0beta1
49

510
- Core:
611
. Fixed bug #81238 (Fiber support missing for Solaris Sparc). (trowski)
@@ -11,6 +16,8 @@ PHP NEWS
1116
(Dmitry)
1217
. Fixed bug #81249 (Intermittent property assignment failure with JIT
1318
enabled). (Dmitry)
19+
. Fixed bug #81256 (Assertion `zv != ((void *)0)' failed for "preload" with
20+
JIT). (Dmitry)
1421

1522
- Reflection:
1623
. Fixed bug #80097 (ReflectionAttribute is not a Reflector). (beberlei)

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ PHP 8.1 UPGRADE NOTES
206206
RFC: https://wiki.php.net/rfc/pure-intersection-types
207207
. Added support for the final modifier for class constants.
208208
RFC: https://wiki.php.net/rfc/final_class_const
209+
. Added support for readonly properties.
210+
RFC: https://wiki.php.net/rfc/readonly_properties_v2
209211

210212
- Curl:
211213
. Added CURLOPT_DOH_URL option.

UPGRADING.INTERNALS

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ PHP 8.1 INTERNALS UPGRADE NOTES
5151
macro. Replace ZEND_ATOL(i, s) with i = ZEND_ATOL(s).
5252
f. Non-serializable classes should be indicated using the
5353
ZEND_ACC_NOT_SERIALIZABLE (@not-serializable in stubs) rather than the
54-
zend_class_(un)serialize_deny handlers. Support for the serialization
55-
handlers will be dropped in the future.
54+
zend_class_(un)serialize_deny handlers which are removed.
5655
g. _zend_hash_find_known_hash has been renamed to zend_hash_find_known_hash.
5756

5857
========================

Zend/Optimizer/zend_func_info.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,9 @@ static const func_info_t func_infos[] = {
346346
F0("uasort", MAY_BE_TRUE),
347347
F0("uksort", MAY_BE_TRUE),
348348
F1("compact", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
349-
F1("array_fill", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ANY),
349+
FN("array_fill", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ANY),
350350
F1("array_fill_keys", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
351351
FC("range", zend_range_info),
352-
F1("array_splice", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
353-
F1("array_slice", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
354352
F1("array_replace", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
355353
F1("array_replace_recursive", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
356354
FN("array_keys", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
@@ -376,9 +374,6 @@ static const func_info_t func_infos[] = {
376374
F1("array_udiff_assoc", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
377375
F1("array_diff_uassoc", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
378376
F1("array_udiff_uassoc", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
379-
F1("array_filter", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
380-
F1("array_chunk", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
381-
F1("array_combine", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY),
382377
F1("str_rot13", MAY_BE_STRING),
383378
F1("stream_get_filters", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING),
384379
F1("stream_bucket_make_writeable", MAY_BE_NULL | MAY_BE_OBJECT),
@@ -538,7 +533,7 @@ static const func_info_t func_infos[] = {
538533

539534
/* ext/json */
540535
F1("json_encode", MAY_BE_FALSE | MAY_BE_STRING),
541-
F1("json_decode", MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
536+
FN("json_decode", MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
542537
F1("json_last_error_msg", MAY_BE_STRING),
543538

544539
/* ext/xml */
@@ -695,7 +690,7 @@ static const func_info_t func_infos[] = {
695690
F1("pg_get_result", MAY_BE_FALSE | MAY_BE_OBJECT),
696691
F1("pg_result_status", MAY_BE_LONG | MAY_BE_STRING),
697692
F1("pg_get_notify", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
698-
F1("pg_socket", MAY_BE_FALSE | MAY_BE_OBJECT),
693+
F1("pg_socket", MAY_BE_FALSE | MAY_BE_RESOURCE),
699694
F1("pg_meta_data", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY),
700695
F1("pg_convert", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY),
701696
F1("pg_insert", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_OBJECT | MAY_BE_STRING),

Zend/tests/grammar/semi_reserved_001.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Obj
4545
function array(){ echo __METHOD__, PHP_EOL; }
4646
function print(){ echo __METHOD__, PHP_EOL; }
4747
function echo(){ echo __METHOD__, PHP_EOL; }
48+
function readonly(){ echo __METHOD__, PHP_EOL; }
4849
function require(){ echo __METHOD__, PHP_EOL; }
4950
function require_once(){ echo __METHOD__, PHP_EOL; }
5051
function return(){ echo __METHOD__, PHP_EOL; }
@@ -125,6 +126,7 @@ $obj->throw();
125126
$obj->array();
126127
$obj->print();
127128
$obj->echo();
129+
$obj->readonly();
128130
$obj->require();
129131
$obj->require_once();
130132
$obj->return();
@@ -205,6 +207,7 @@ Obj::throw
205207
Obj::array
206208
Obj::print
207209
Obj::echo
210+
Obj::readonly
208211
Obj::require
209212
Obj::require_once
210213
Obj::return
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
By-ref foreach over readonly property
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public readonly int $prop;
8+
9+
public function init() {
10+
$this->prop = 1;
11+
}
12+
}
13+
14+
$test = new Test;
15+
16+
// Okay, as foreach skips over uninitialized properties.
17+
foreach ($test as &$prop) {}
18+
19+
$test->init();
20+
21+
try {
22+
foreach ($test as &$prop) {}
23+
} catch (Error $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
27+
?>
28+
--EXPECT--
29+
Cannot acquire reference to readonly property Test::$prop
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
--TEST--
2+
Test interaction with cache slots
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public readonly string $prop;
8+
public readonly array $prop2;
9+
public readonly object $prop3;
10+
public function setProp(string $prop) {
11+
$this->prop = $prop;
12+
}
13+
public function initAndAppendProp2() {
14+
$this->prop2 = [];
15+
$this->prop2[] = 1;
16+
}
17+
public function initProp3() {
18+
$this->prop3 = new stdClass;
19+
$this->prop3->foo = 1;
20+
}
21+
public function replaceProp3() {
22+
$ref =& $this->prop3;
23+
$ref = new stdClass;
24+
}
25+
}
26+
27+
$test = new Test;
28+
$test->setProp("a");
29+
var_dump($test->prop);
30+
try {
31+
$test->setProp("b");
32+
} catch (Error $e) {
33+
echo $e->getMessage(), "\n";
34+
}
35+
var_dump($test->prop);
36+
echo "\n";
37+
38+
$test = new Test;
39+
try {
40+
$test->initAndAppendProp2();
41+
} catch (Error $e) {
42+
echo $e->getMessage(), "\n";
43+
}
44+
try {
45+
$test->initAndAppendProp2();
46+
} catch (Error $e) {
47+
echo $e->getMessage(), "\n";
48+
}
49+
var_dump($test->prop2);
50+
echo "\n";
51+
52+
$test = new Test;
53+
$test->initProp3();
54+
$test->replaceProp3();
55+
var_dump($test->prop3);
56+
$test->replaceProp3();
57+
var_dump($test->prop3);
58+
echo "\n";
59+
60+
// Test variations using closure rebinding, so we have unknown property_info in JIT.
61+
$test = new Test;
62+
(function() { $this->prop2 = []; })->call($test);
63+
$appendProp2 = (function() {
64+
$this->prop2[] = 1;
65+
})->bindTo($test, Test::class);
66+
try {
67+
$appendProp2();
68+
} catch (Error $e) {
69+
echo $e->getMessage(), "\n";
70+
}
71+
try {
72+
$appendProp2();
73+
} catch (Error $e) {
74+
echo $e->getMessage(), "\n";
75+
}
76+
var_dump($test->prop2);
77+
echo "\n";
78+
79+
$test = new Test;
80+
$replaceProp3 = (function() {
81+
$ref =& $this->prop3;
82+
$ref = new stdClass;
83+
})->bindTo($test, Test::class);
84+
$test->initProp3();
85+
$replaceProp3();
86+
var_dump($test->prop3);
87+
$replaceProp3();
88+
var_dump($test->prop3);
89+
90+
?>
91+
--EXPECT--
92+
string(1) "a"
93+
Cannot modify readonly property Test::$prop
94+
string(1) "a"
95+
96+
Cannot modify readonly property Test::$prop2
97+
Cannot modify readonly property Test::$prop2
98+
array(0) {
99+
}
100+
101+
object(stdClass)#3 (1) {
102+
["foo"]=>
103+
int(1)
104+
}
105+
object(stdClass)#3 (1) {
106+
["foo"]=>
107+
int(1)
108+
}
109+
110+
Cannot modify readonly property Test::$prop2
111+
Cannot modify readonly property Test::$prop2
112+
array(0) {
113+
}
114+
115+
object(stdClass)#5 (1) {
116+
["foo"]=>
117+
int(1)
118+
}
119+
object(stdClass)#5 (1) {
120+
["foo"]=>
121+
int(1)
122+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
--TEST--
2+
Initialization can only happen from private scope
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public readonly int $prop;
8+
9+
public function initPrivate() {
10+
$this->prop = 3;
11+
}
12+
}
13+
class B extends A {
14+
public function initProtected() {
15+
$this->prop = 2;
16+
}
17+
}
18+
19+
$test = new B;
20+
try {
21+
$test->prop = 1;
22+
} catch (Error $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
try {
26+
$test->initProtected();
27+
} catch (Error $e) {
28+
echo $e->getMessage(), "\n";
29+
}
30+
31+
$test->initPrivate();
32+
var_dump($test->prop);
33+
34+
// Rebinding bypass works.
35+
$test = new B;
36+
(function() {
37+
$this->prop = 1;
38+
})->bindTo($test, A::class)();
39+
var_dump($test->prop);
40+
41+
class C extends A {
42+
public readonly int $prop;
43+
}
44+
45+
$test = new C;
46+
$test->initPrivate();
47+
var_dump($test->prop);
48+
49+
class X {
50+
public function initFromParent() {
51+
$this->prop = 1;
52+
}
53+
}
54+
class Y extends X {
55+
public readonly int $prop;
56+
}
57+
58+
$test = new Y;
59+
try {
60+
$test->initFromParent();
61+
} catch (Error $e) {
62+
echo $e->getMessage(), "\n";
63+
}
64+
65+
?>
66+
--EXPECT--
67+
Cannot initialize readonly property A::$prop from global scope
68+
Cannot initialize readonly property A::$prop from scope B
69+
int(3)
70+
int(1)
71+
int(3)
72+
Cannot initialize readonly property Y::$prop from scope X

0 commit comments

Comments
 (0)