Skip to content

PHP 8.6: Optimized printf changes compile-time acceptance of discarded expressions #24794

Closed as not planned

Description

@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
printf(true || (unset)$x);

Actual behavior:

  • PHP 8.5.10: Compilation succeeds.
  • PHP 8.6.0RC4: Compilation fails with:
Fatal error: The (unset) cast is no longer supported

Dynamic-call control

<?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
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:

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

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

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

Activity

  1. iluuu1994 commented on Oct 27, 2026

    @iluuu1994
    Member

    Hi @alwyn1024. Thanks for the report. As with GH-24795, this has the same root cause. This is unrelated to printf(), true || (unset)$x alone reproduces the issue. So I'm closing this as a wontfix with the same argumentation. Thanks anyway. 🙂

  2. alwyn1024 commented on Oct 28, 2026

    @alwyn1024
    Author

    Thank you for clarifying @iluuu1994 , much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions