1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

3052 Commits

Author SHA1 Message Date
Gina Peter Banyard
113893b714 Zend: create a IS_VOID type AST rather a string (#21415) 2026-03-11 22:39:09 +00:00
Gina Peter Banyard
6880a6c49d Zend: mark scope parameter of zend_type_to_string_resolved() const
And propagate const qualifier to use sites of this function.
2026-03-09 21:41:06 +00:00
Gina Peter Banyard
8bff644233 Zend: remove unused scope parameter of add_intersection_type() 2026-03-09 21:41:06 +00:00
Ilija Tovilo
27d28eef1e Fix mistakenly allowed assignment to assignment through list operator (GH-21123)
Fixes OSS-Fuzz #480111866
Introduced in GH-20628
2026-02-04 01:47:01 +01:00
Arnaud Le Blanc
d16e6f52a4 Generate C enums from internal enums, introduce Z_PARAM_ENUM() (#20917)
Update gen_stubs.php to generate C enums from internal enums, when the stub is annotated with @generate-c-enums. Enum values can be compared to the result of zend_enum_fetch_case_id(zend_object*).

The generated enums are added to separate files named {$extensionName}_decl.h, so that it's possible to include these from anywhere. _arginfo.h files would generate warnings if we tried to include them in a compilation unit that doesn't call the register_{$class} functions, for instance.

Introduce Z_PARAM_ENUM().

* Make ZEND_AST_CONST_ENUM_INIT a 4-children node

* Store enum case id in ZEND_AST_CONST_ENUM_INIT

* Store enum case id in instance

* Expose enum case_id internally

* Generate C enum for internal enums

* Introduce Z_PARAM_ENUM()

* Port extensions
2026-02-03 12:38:04 +01:00
Khaled Alam
32bd33983d Remove unreachable code after zend_error_noreturn calls (GH-20983) 2026-02-02 14:14:15 +01:00
Ilija Tovilo
a01a8e72ac Fix failed assertion for assignment in expression context
This code path is reachable for all assignments expressions, not just true
variable expressions.

Really surprising we have no tests that caught this.
2026-02-01 14:14:08 +01:00
Ilija Tovilo
6173a9a109 VAR|TMP overhaul (GH-20628)
The aim of this PR is twofold:

- Reduce the number of highly similar TMP|VAR handlers
- Avoid ZVAL_DEREF in most of these cases

This is achieved by guaranteeing that all zend_compile_expr() calls, as well as
all other compile calls with BP_VAR_{R,IS}, will result in a TMP variable. This
implies that the result will not contain an IS_INDIRECT or IS_REFERENCE value,
which was mostly already the case, with two exceptions:

- Calls to return-by-reference functions. Because return-by-reference functions
  are quite rare, this is solved by delegating the DEREF to the RETURN_BY_REF
  handler, which will examine the stack to check whether the caller expects a
  VAR or TMP to understand whether the DEREF is needed. Internal functions will
  also need to adjust by calling the zend_return_unwrap_ref() function.

- By-reference assignments, including both $a = &$b, as well as $a = [&$b]. When
  the result of these expressions is used in a BP_VAR_R context, the reference
  is unwrapped via a ZEND_QM_ASSIGN opcode beforehand. This is exceptionally
  rare.

Closes GH-20628
2026-01-31 19:44:56 +01:00
Arshid
3bff1dc875 Remove unused arg from zend_property_is_virtual() (GH-21084) 2026-01-30 14:21:11 +01:00
Ilija Tovilo
0dd1bdc3e5 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix crash on (unset) cast in constant expression
2026-01-29 17:00:43 +01:00
arshidkv12
e9ae040629 Fix crash on (unset) cast in constant expression
Fixes GH-21072
Closes GH-21073
2026-01-29 17:00:06 +01:00
Tim Düsterhus
6a17febe6c zend_compile: Fix array_map() optimization (#21016)
* zend_compile: Fix handling of PFA syntax in array_map() optimization

PFA is not implemented and the syntax is rejected at compile-time, thus it was
assumed the assertion would be unreachable. However the check for PFA syntax
happens after compiling special functions, making it reachable. Fix this by
gracefully returning FAILURE which will then correctly emit the error during
the compilation of the normal call.

Fixes php/php-src#20991.

* zend_compile: Fix array_map() optimization for dynamic function names

Fixes php/php-src#20990.

* zend_compile: Adjust array_map() optimization after review feedback
2026-01-26 08:59:30 +01:00
Tim Düsterhus
a3576bddc5 zend_compile: Optimize array_map() with callable convert callback into foreach (#20934)
* zend_compile: Optimize `array_map()` with callable convert callback into foreach

For:

    <?php

    function plus1($x) {
    	return $x + 1;
    }

    $array = array_fill(0, 100, 1);

    $count = 0;
    for ($i = 0; $i < 100_000; $i++) {
    	$count += count(array_map(plus1(...), $array));
    }

    var_dump($count);

This is ~1.1× faster:

    Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php
      Time (mean ± σ):     172.2 ms ±   0.5 ms    [User: 167.8 ms, System: 4.2 ms]
      Range (min … max):   171.6 ms … 173.1 ms    17 runs

    Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php
      Time (mean ± σ):     155.1 ms ±   1.3 ms    [User: 150.6 ms, System: 4.2 ms]
      Range (min … max):   154.2 ms … 159.3 ms    18 runs

    Summary
      /tmp/test/after -d opcache.enable_cli=1 /tmp/test/test6.php ran
        1.11 ± 0.01 times faster than /tmp/test/before -d opcache.enable_cli=1 /tmp/test/test6.php

With JIT it becomes ~1.7× faster:

    Benchmark 1: /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php
      Time (mean ± σ):     166.9 ms ±   0.6 ms    [User: 162.7 ms, System: 4.1 ms]
      Range (min … max):   166.1 ms … 167.9 ms    17 runs

    Benchmark 2: /tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php
      Time (mean ± σ):      94.5 ms ±   2.7 ms    [User: 90.4 ms, System: 3.9 ms]
      Range (min … max):    92.5 ms … 103.1 ms    31 runs

    Summary
      /tmp/test/after -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php ran
        1.77 ± 0.05 times faster than /tmp/test/before -d opcache.enable_cli=1 -d opcache.jit=tracing /tmp/test/test6.php

* zend_compile: Skip `assert(...)` callbacks for array_map() optimization

* zend_compile: Remove `zend_eval_const_expr()` in array_map optimization

* zend_vm_def: Check simple types without loading the arginfo in ZEND_TYPE_ASSERT

* zend_vm_def: Handle references for ZEND_TYPE_ASSERT

* zend_compile: Fix handling of constant arrays for `array_map()`

* zend_compile: Fix leak of unused result in array_map() optimization

* zend_compile: Support static methods for `array_map()` optimization

* UPGRADING
2026-01-19 10:18:24 +01:00
Arnaud Le Blanc
5472cac806 Support PFA syntax
RFC: https://wiki.php.net/rfc/partial_function_application_v2

For FCCs, the parser generates a normal function call AST node, the but argument
list is a ZEND_AST_CALLABLE_CONVERT / zend_ast_fcc node.

We extend this for PFAs so that zend_ast_fcc can represent arguments.

 * Support PFA syntax in grammar
 * Update zend_ast_fcc so that arguments can be represented
 * Support serialization of zend_ast_fcc arguments in SHM / file cache
 * Introduce zend_ast_arg_list_add(): Same as zend_ast_list_add(), but wraps the
   list in a ZEND_AST_CALLABLE_CONVERT when adding any placeholder argument.

Technically the arg list wrapping is not required, but it results in simpler
code later as it will be very convenient in the compiler (determines whether a
function calls is a PFA/FCC), and for PFA-in-const-expr support. It also allows
to unify FCCs and PFAs in the grammar.

Closes GH-20717.
2026-01-06 12:01:48 +01:00
Ilija Tovilo
610361845b Remove unnecessary optimization FIXME
As the comment suggests, the return value of frameless calls is rarely not used.
When it isn't used (and isn't refcounted) the FREE is already elided by the
optimizer.

Closes GH-20819
2026-01-02 17:08:28 +01:00
Arnaud Le Blanc
626f3c3c7c Unify arg info representation for internal and user functions
The arg_info member of zend_function is now always a zend_arg_info*. Before,
it was a zend_internal_arg_info* on internal functions, unless the
ZEND_ACC_USER_ARG_INFO flag was set.

Closes GH-19022
2025-12-15 16:50:49 +01:00
Daniel Scherzer
980bd0ee5d Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-20377: emit assignment for all final promoted properties (#20378)
2025-11-03 14:37:39 -08:00
Daniel Scherzer
e5c6456d37 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.
2025-11-03 14:36:57 -08:00
Gina Peter Banyard
c669fbf370 Zend/zend_compile: add const qualifiers 2025-10-30 12:02:43 +00:00
Gina Peter Banyard
ee40791aff Zend/zend_compile.c: remove unused fbc parameter of zend_try_compile_special_func_ex() 2025-10-30 12:02:43 +00:00
Gina Peter Banyard
0df31e5a5b Merge branch 'PHP-8.5'
* PHP-8.5:
  Update NEWS for null deprecation bug fix
  Fix GH-20194: null offset deprecation not emitted for writes (#20238)
2025-10-29 18:37:29 +00:00
Gina Peter Banyard
9a1b8a785d Fix GH-20194: null offset deprecation not emitted for writes (#20238)
Based on a patch from @ndossche
2025-10-29 18:36:10 +00:00
Tim Düsterhus
025e16cb54 zend_compile: Optimize arguments for ZEND_NEW (#20259)
* zend_compile: Add `is_func_accessible()` helper

* zend_compile: Use `zend_set_class_name_op1()` in `zend_compile_new()`

* zend_compile: Optimize arguments for ZEND_NEW

Apply the optimization for static method calls to `new` calls, since `new` is
effectively a static method for all intents and purposes.

For:

    <?php

    final class MyClass
    {
    	private function __construct(
    		private \Random\Engine $foo,
    		private int $bar = 0,
    	) {}

    	public static function new(int $bar): self
    	{
    		$engine = new \Random\Engine\Xoshiro256StarStar(seed: 123);
    		return new self(foo: $engine, bar: $bar);
    	}
    }

    for ($i = 0; $i < 3_000_000; $i++) {
    	MyClass::new($i);
    }

This is ~1.13 faster for a gcc 13.3 release build on a Intel(R) Core(TM)
i7-1365U.

    Benchmark 1: /tmp/bench/php.old /tmp/bench/test6.php
      Time (mean ± σ):     409.5 ms ±   1.9 ms    [User: 406.6 ms, System: 2.2 ms]
      Range (min … max):   407.4 ms … 414.0 ms    10 runs

    Benchmark 2: /tmp/bench/php.new /tmp/bench/test6.php
      Time (mean ± σ):     360.9 ms ±   1.7 ms    [User: 358.5 ms, System: 2.2 ms]
      Range (min … max):   359.2 ms … 365.0 ms    10 runs

    Summary
      /tmp/bench/php.new /tmp/bench/test6.php ran
        1.13 ± 0.01 times faster than /tmp/bench/php.old /tmp/bench/test6.php
2025-10-23 09:28:19 +02:00
Niels Dossche
09c39a8fd9 Fix OSS-Fuzz #454273637: UAF with printf optimization and const output (#20261)
Note that ZEND_COPY_TMP isn't even valid for CONSTs, and we would need
to add a ref even if it were, so just add special handling instead to
simplify it.
2025-10-23 08:23:55 +02:00
Gina Peter Banyard
d0ad286ec8 Zend: use type uint32_t for zend_lineno global 2025-10-21 22:42:00 +01:00
Tim Düsterhus
0a7695cd5a Merge branch 'PHP-8.5'
* PHP-8.5:
  PHP 8.5 | UPGRADING: fix entry about new grapheme $locale parameter (#20239)
  uri: Make uri_parser_rfc3986.h usable for external extensions (#20173)
  Fix missing deprecation message for default case statement followed by semicolon (#20172)
2025-10-20 10:32:14 +02:00
Theodore Brown
c03215b623 Fix missing deprecation message for default case statement followed by semicolon (#20172)
Follow-up to GH-19215
2025-10-20 10:29:54 +02:00
Florian Engelhardt
26c96d38f4 re-use sprintf() optimisation for printf()
Closes GH-19658
2025-10-17 13:34:29 +02:00
Ilija Tovilo
e7524570f2 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix missing new Foo(...) error in constant expressions
2025-10-09 19:09:30 +02:00
Ilija Tovilo
5a63f7a54b Fix missing new Foo(...) error in constant expressions
Though first-class callables are now supported in constant expressions, they
remain unsupported for the new expression.

Fixes GH-20113
Closes GH-20115
2025-10-09 19:09:01 +02:00
Tim Düsterhus
985d681501 tree-wide: Replace zval_is_true() by zend_is_true() (#20065)
* tree-wide: Replace `zval_is_true()` by `zend_is_true()`

The former is a direct alias of the latter which is much more often used.

* zend_operators: Remove `zval_is_true()`
2025-10-07 20:44:32 +02:00
Jakub Zelenka
c07b9cc49d Merge branch 'PHP-8.5' 2025-10-06 10:32:28 +02:00
Nicolas Grekas
fc353966f3 Revert deprecation of __sleep and __wakeup (#19966) 2025-10-06 10:30:27 +02:00
Niels Dossche
e99df67869 Fix uouv in recursive implicit bind computation (#20056)
Regressed in 5c956f98.
Moved the initialization to prevent future regressions.
Fixes last nightly.
2025-10-04 12:58:29 +02:00
Ilija Tovilo
5c956f9838 Avoid capturing nested arrow function parameters
Fixes GH-19867
Closes GH-20041
2025-10-03 23:16:21 +02:00
Niels Dossche
f9c4fe4c5d [ci skip] Fix indent 2025-10-03 22:30:37 +02:00
Niels Dossche
969e837d5b Fix compiler segfault during call compilation (#20054)
Happens due to changes in 28fd7597ba where the opline opcode may be
accessed after the opcode array has been reallocated.
To solve this we store the opcode in a temporary variable.
2025-10-03 22:30:07 +02:00
Ilija Tovilo
28fd7597ba Add first-class callable cache
This cache is implemented in two levels: A EG(callable_convert_cache) global
that maps zend_function pointers to a shared callable instance, and a
CALLABLE_CONVERT cache slot to remember the result of the hash table lookup.

Fixes GH-19754
Closes GH-19863
2025-10-03 01:04:56 +02:00
Ilija Tovilo
292e0c2937 Add ce_flags2 & fn_flags2 (GH-19991) 2025-09-30 22:54:59 +02:00
Ilija Tovilo
cc80a2baea Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix fatal error during sccp shift eval
2025-09-30 01:17:09 +02:00
Ilija Tovilo
16a8591f28 Fix fatal error during sccp shift eval
Avoid returning early in this function, as other checks might still be needed to
verify whether the given function can procude an error.

Fixes oss-fuzz #447521098
Closes GH-19972
2025-09-30 01:16:40 +02:00
Gina Peter Banyard
c515c04b0a Zend: Convert _zend_op_array literal fields to uint32_t 2025-09-29 15:53:58 +01:00
Gina Peter Banyard
0a47dd9bb4 Zend: Convert _zend_op_array.last_try_catch field to uint32_t 2025-09-29 15:53:58 +01:00
Gina Peter Banyard
299bd63177 Zend: Change return type of lookup_cv from int to uint32_t 2025-09-29 15:53:58 +01:00
Tim Düsterhus
c9b175992c Zend: Use true / false instead of 1 / 0 for bool parameters
Changes done with Coccinelle:

    @r1@
    identifier F;
    identifier p;
    typedef bool;
    parameter list [n1] PL1;
    parameter list [n2] PL2;
    @@

    F(PL1, bool p, PL2) {
    ...
    }

    @r2@
    identifier r1.F;
    expression list [r1.n1] EL1;
    expression list [r1.n2] EL2;
    @@

    F(EL1,
    (
    - 1
    + true
    |
    - 0
    + false
    )
    , EL2)
2025-09-24 18:51:40 +02:00
Tim Düsterhus
c32fbca874 Zend: Use true / false instead of 1 / 0 when assigning to bool
Changes done with Coccinelle:

    @@
    bool b;
    @@

    - b = 0
    + b = false

    @@
    bool b;
    @@

    - b = 1
    + b = true
2025-09-24 18:51:40 +02:00
Ilija Tovilo
8b51bcaa18 Fix CGI with auto_globals_jit=0
In CGI, php_auto_globals_create_server() (i.e. auto_global_callback() here)
initializes $_ENV to reuse for $_SERVER. However, because $_SERVER is
constructed first, we have not yet initialized auto_global->armed of the $_ENV
global. Split the loop into initialization and constructor phases.

Closes GH-19870
2025-09-23 16:53:11 +02:00
Gina Peter Banyard
320fe2975b core: Warn when coercing NAN to other types
RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types

Closes GH-19573
2025-09-23 11:16:51 +01:00
Gina Peter Banyard
b4ed215299 core: Warn when non-representable floats are coerced to int (#19760)
RFC: https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int
2025-09-21 23:53:16 +01:00
Niels Dossche
1f6ac30769 Allow empty statements before declare(strict_types)
Fixes GH-19719
Closes GH-19859
2025-09-21 19:36:59 +02:00