[php-src] Issue #24794: PHP 8.6: Optimized printf changes compile-time acceptance of discarded expressions
| From: | alwyn1024 | Date: | Tue, 27 Oct 2026 16:56:30 +0000 |
| Subject: | [php-src] Issue #24794: PHP 8.6: Optimized printf changes compile-time acceptance of discarded expressions | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-253246@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24794
Author: alwyn1024
### Description
## Summary
PHP 8.6.0RC4 changes whether certain expressions containing an unsupported
(unset) cast
are accepted during compilation, depending on whether a function call follows an optimized or
ordinary compilation path.
This produces different results for direct printf() calls and dynamic calls. Some
expressions accepted by PHP 8.5 are rejected by PHP 8.6, while other expressions previously rejected
are now accepted.
## Minimal reproducer
```php
<?php
printf(true || (unset)$x);
```
**Actual behavior:**
- PHP 8.5.10: Compilation succeeds.
- PHP 8.6.0RC4: Compilation fails with:
```text
Fatal error: The (unset) cast is no longer supported
```
### Dynamic-call control
```php
<?php
$f = "printf";
$f(true || (unset)$x);
```
Both PHP 8.5.10 and PHP 8.6.0RC4 accept this during compilation.
### Opposite acceptance difference
```php
<?php
printf(false ? (unset)$x : "ok");
```
- PHP 8.5.10: Compilation fails with the unsupported (unset) cast diagnostic.
- PHP 8.6.0RC4: Compilation succeeds.
These results occur during compilation, without executing the examples.
## Expected behavior / clarification requested
Is optimization-specific traversal intended to change compile-time PHP source validity, or should
optimized and ordinary calls enforce the same validity rules?
In particular, which behavior is intended for the logical short-circuit and conditional-expression
examples above?
Related observations involve sprintf(), qualified and imported calls, named arguments,
unpacking, partial function application, and constant initializers. These appear to follow different
compilation paths, but the examples above demonstrate the central inconsistency.
## Affected versions
- PHP 8.5.10 — Windows x64
- PHP 8.6.0RC4 — Windows x64, NTS, VC2022
- PHP 8.6 source commit: f23b4c222cebe33be93ee8ecaaa14390c5507a08
The PHP 8.6 executable was built from the specified source commit.
Reproduce with:
```powershell
php -n -l example.php
```
CLI OPcache and JIT were disabled. This behaviour is related to compiler lowering and
constant-expression traversal, not runtime optimization.
## Relevant implementation
-
[[zend_compile_func_printf](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L5264)](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L5264)
-
[[zend_compile_func_sprintf](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L5096)](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L5096)
-
[[zend_eval_const_expr](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L12920)](https://github.com/php/php-src/blob/f23b4c222cebe33be93ee8ecaaa14390c5507a08/Zend/zend_compile.c#L12920)
- [[Related PR
#19658](https://github.com/php/php-src/pull/19658)](https://github.com/php/php-src/pull/19658)
The optimized call compilation path appears to traverse constant expressions differently from
ordinary call compilation.
I would appreciate clarification on whether these differences are intentional language behaviour or
an unintended consequence of compilation optimization.
### PHP Version
```plain
PHP 8.6.0RC4 (cli) (built: Oct 25 2026 12:45:36) (NTS Visual C++ 2022 x64)
Copyright © The PHP Group and Contributors
Zend Engine v4.6.0RC4, Copyright © Zend by Perforce
with Zend OPcache v8.6.0RC4, Copyright ©, by Zend by Perforce
```
### Operating System
Windows x64 (64-bit), MSVC 2022 build