Skip to content

Commit ecba43a

Browse files
committed
Merge branch 'master' into override-property
2 parents 52af261 + 65c9614 commit ecba43a

File tree

90 files changed

+765
-226
lines changed

Some content is hidden

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

90 files changed

+765
-226
lines changed

.github/workflows/nightly.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@ jobs:
10681068
- zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }}
10691069
name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}"
10701070
runs-on: ubuntu-latest
1071+
timeout-minutes: 50
10711072
steps:
10721073
- name: git checkout
10731074
uses: actions/checkout@v4

.github/workflows/push.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ jobs:
366366
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
367367
name: FREEBSD
368368
runs-on: ubuntu-latest
369+
timeout-minutes: 50
369370
steps:
370371
- name: git checkout
371372
uses: actions/checkout@v4

NEWS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ PHP NEWS
99
been deprecated, as it no longer has any effect since PHP 8.0. (Girgias)
1010
. Terminating case statements with a semicolon instead of a colon has
1111
been deprecated. (theodorejb)
12+
. The backtick operator as an alias for shell_exec() has been deprecated.
13+
(timwolla)
14+
. Returning null from __debugInfo() has been deprecated. (DanielEScherzer)
15+
16+
- Date:
17+
. The DATE_RFC7231 and DateTimeInterface::RFC7231 constants have been
18+
deprecated. (jorgsowa)
1219

1320
- DOM:
1421
. Fixed bug GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the
@@ -36,6 +43,8 @@ PHP NEWS
3643
(Girgias)
3744
. Implement #80495 (Enable to set padding in openssl_(sign|verify).
3845
(Jakub Zelenka)
46+
. Implement #47728 (openssl_pkcs7_sign ignores new openssl flags).
47+
(Jakub Zelenka)
3948

4049
- PDO:
4150
. The "uri:" DSN scheme has been deprecated due to security concerns with
@@ -62,6 +71,8 @@ PHP NEWS
6271
. The socket_set_timeout() alias function has been deprecated. (timwolla)
6372
. Passing null to to readdir(), rewinddir(), and closedir() to use the last
6473
opened directory has been deprecated. (Girgias)
74+
. Fixed bug GH-19153 (#[\Attribute] validation should error on
75+
trait/interface/enum/abstract class). (DanielEScherzer)
6576

6677
31 Jul 2025, PHP 8.5.0alpha4
6778

UPGRADING

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ PHP 8.5 UPGRADE NOTES
5050
immediately, without calling user-defined error handlers.
5151
. Exceptions thrown by user-defined error handlers when handling class linking
5252
errors are not promoted to fatal errors anymore and do not prevent linking.
53+
. Applying #[\Attribute] to an abstract class, enum, interface, or trait triggers
54+
an error during compilation. Previously, the attribute could be added, but when
55+
ReflectionAttribute::newInstance() was called an error would be thrown.
5356

5457
- DOM:
5558
. Cloning a DOMNamedNodeMap, DOMNodeList, Dom\NamedNodeMap, Dom\NodeList,
@@ -325,6 +328,17 @@ PHP 8.5 UPGRADE NOTES
325328
. Terminating case statements with a semicolon instead of a colon has
326329
been deprecated.
327330
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement
331+
. The backtick operator as an alias for shell_exec() has been deprecated.
332+
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_backticks_as_an_alias_for_shell_exec
333+
. Returning null from __debugInfo() has been deprecated.
334+
Return an empty array instead.
335+
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_debuginfo_returning_null
336+
337+
- Date:
338+
. The DATE_RFC7231 and DateTimeInterface::RFC7231 constants have been
339+
deprecated. This is because the associated timezone is ignored and always
340+
uses GMT.
341+
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_date_rfc7231_and_datetimeinterfacerfc7231
328342

329343
- FileInfo:
330344
. The finfo_close() function has been deprecated.
@@ -671,6 +685,10 @@ PHP 8.5 UPGRADE NOTES
671685

672686
- OpenSSL:
673687
. OPENSSL_PKCS1_PSS_PADDING
688+
. PKCS7_NOSMIMECAP
689+
. PKCS7_CRLFEOL
690+
. PKCS7_NOCRL
691+
. PKCS7_NO_DUAL_CONTENT
674692

675693
- POSIX:
676694
. POSIX_SC_OPEN_MAX.

Zend/Optimizer/block_pass.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,14 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
420420
}
421421
break;
422422

423+
case ZEND_EXT_STMT:
424+
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
425+
/* Variable will be deleted later by FREE, so we can't optimize it */
426+
Tsource[VAR_NUM(opline->op1.var)] = NULL;
427+
break;
428+
}
429+
break;
430+
423431
case ZEND_CASE:
424432
case ZEND_CASE_STRICT:
425433
case ZEND_COPY_TMP:

Zend/Optimizer/zend_ssa.c

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "zend_ssa.h"
2323
#include "zend_dump.h"
2424
#include "zend_inference.h"
25+
#include "zend_worklist.h"
2526
#include "Optimizer/zend_optimizer_internal.h"
2627

2728
static bool dominates(const zend_basic_block *blocks, int a, int b) {
@@ -816,23 +817,14 @@ ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *op
816817
}
817818
/* }}} */
818819

819-
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
820+
static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
820821
{
821822
zend_basic_block *blocks = ssa->cfg.blocks;
822823
zend_ssa_block *ssa_blocks = ssa->blocks;
823824
zend_ssa_op *ssa_ops = ssa->ops;
824825
int ssa_vars_count = ssa->vars_count;
825826
int i, j;
826827
zend_op *opline, *end;
827-
int *tmp = NULL;
828-
ALLOCA_FLAG(use_heap = 0);
829-
830-
// FIXME: Can we optimize this copying out in some cases?
831-
if (blocks[n].next_child >= 0) {
832-
tmp = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), use_heap);
833-
memcpy(tmp, var, sizeof(int) * (op_array->last_var + op_array->T));
834-
var = tmp;
835-
}
836828

837829
if (ssa_blocks[n].phis) {
838830
zend_ssa_phi *phi = ssa_blocks[n].phis;
@@ -916,22 +908,90 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build
916908
}
917909

918910
ssa->vars_count = ssa_vars_count;
911+
}
912+
/* }}} */
919913

920-
j = blocks[n].children;
921-
while (j >= 0) {
922-
// FIXME: Tail call optimization?
923-
if (zend_ssa_rename(op_array, build_flags, ssa, var, j) == FAILURE)
924-
return FAILURE;
925-
j = blocks[j].next_child;
914+
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n)
915+
{
916+
/* The worklist contains block numbers, encoded as positive or negative value.
917+
* Positive values indicate that the variable rename still needs to happen for the block.
918+
* Negative values indicate the variable rename was done and all children were handled too.
919+
* In that case, we will clean up.
920+
* Because block 0 is valid, we bias the block numbers by adding 1 such that we can distinguish
921+
* positive and negative values in all cases. */
922+
zend_worklist_stack work;
923+
ALLOCA_FLAG(work_use_heap);
924+
ZEND_WORKLIST_STACK_ALLOCA(&work, ssa->cfg.blocks_count, work_use_heap);
925+
zend_worklist_stack_push(&work, n + 1);
926+
927+
/* This is used to backtrack the right version of the renamed variables to use. */
928+
ALLOCA_FLAG(save_vars_use_heap);
929+
unsigned int save_vars_top = 0;
930+
int **save_vars = do_alloca(sizeof(int *) * (ssa->cfg.blocks_count + 1), save_vars_use_heap);
931+
save_vars[0] = var;
932+
933+
while (work.len) {
934+
n = zend_worklist_stack_pop(&work);
935+
936+
/* Enter state: perform SSA variable rename */
937+
if (n > 0) {
938+
n--;
939+
940+
// FIXME: Can we optimize this copying out in some cases?
941+
int *new_var;
942+
if (ssa->cfg.blocks[n].next_child >= 0) {
943+
new_var = emalloc(sizeof(int) * (op_array->last_var + op_array->T));
944+
memcpy(new_var, save_vars[save_vars_top], sizeof(int) * (op_array->last_var + op_array->T));
945+
save_vars[++save_vars_top] = new_var;
946+
} else {
947+
new_var = save_vars[save_vars_top];
948+
}
949+
950+
zend_ssa_rename_in_block(op_array, build_flags, ssa, new_var, n);
951+
952+
int j = ssa->cfg.blocks[n].children;
953+
if (j >= 0) {
954+
/* Push backtrack state */
955+
zend_worklist_stack_push(&work, -(n + 1));
956+
957+
/* Push children in enter state */
958+
unsigned int child_count = 0;
959+
int len_prior = work.len;
960+
do {
961+
zend_worklist_stack_push(&work, j + 1);
962+
j = ssa->cfg.blocks[j].next_child;
963+
child_count++;
964+
} while (j >= 0);
965+
966+
/* Reverse block order to maintain SSA variable number order given in previous PHP versions,
967+
* but the data structure doesn't allow reverse dominator tree traversal. */
968+
for (unsigned int i = 0; i < child_count / 2; i++) {
969+
int tmp = work.buf[len_prior + i];
970+
work.buf[len_prior + i] = work.buf[work.len - 1 - i];
971+
work.buf[work.len - 1 - i] = tmp;
972+
}
973+
} else {
974+
/* Leafs jump directly to backtracking */
975+
goto backtrack;
976+
}
977+
}
978+
/* Leave state: backtrack */
979+
else {
980+
n = -n;
981+
n--;
982+
backtrack:;
983+
if (ssa->cfg.blocks[n].next_child >= 0) {
984+
efree(save_vars[save_vars_top]);
985+
save_vars_top--;
986+
}
987+
}
926988
}
927989

928-
if (tmp) {
929-
free_alloca(tmp, use_heap);
930-
}
990+
free_alloca(save_vars, save_vars_use_heap);
991+
ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap);
931992

932993
return SUCCESS;
933994
}
934-
/* }}} */
935995

936996
ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */
937997
{
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
#[Attribute] on an abstract class
3+
--FILE--
4+
<?php
5+
6+
#[Attribute]
7+
abstract class Demo {}
8+
9+
echo "Done\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Cannot apply #[\Attribute] to abstract class Demo in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
#[Attribute] on an enum
3+
--FILE--
4+
<?php
5+
6+
#[Attribute]
7+
enum Demo {}
8+
9+
echo "Done\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Cannot apply #[\Attribute] to enum Demo in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
#[Attribute] on an interface
3+
--FILE--
4+
<?php
5+
6+
#[Attribute]
7+
interface Demo {}
8+
9+
echo "Done\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Cannot apply #[\Attribute] to interface Demo in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
#[Attribute] on a trait
3+
--FILE--
4+
<?php
5+
6+
#[Attribute]
7+
trait Demo {}
8+
9+
echo "Done\n";
10+
?>
11+
--EXPECTF--
12+
Fatal error: Cannot apply #[\Attribute] to trait Demo in %s on line %d

0 commit comments

Comments
 (0)