Skip to content

JIT Regression bug for Psalm in 8.4.19 #21460

Closed

Description

@jorgsowa

Description

There is a regression bug for PHP versions 8.4.19 and 8.5.4 reported in the Psalm repository.

vimeo/psalm#11723

It does work if we disable JIT. Sorry that I don't have a reproducer. I will try to send it later.

PHP Version

PHP 8.4.19 (cli) (built: Mar 12 2026 23:41:32) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.4.19, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.19, Copyright (c), by Zend Technologies
    with Xdebug v3.5.0, Copyright (c) 2002-2025, by Derick Rethans

Operating System

No response

Activity

  1. ndossche commented on Mar 16, 2026

    @ndossche
    Member

    Can you try with the fix linked from #21395 ?

  2. githrdw commented on Mar 16, 2026

    @githrdw

    I have tried to build PHP with the patched IR in JIT, but I still get this error 🤔

    root@bb9a59594557:/app# php --version
    PHP 8.4.20-dev (cli) (built: Mar 16 2026 14:28:17) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.4.20-dev, Copyright (c) Zend Technologies
    
    root@bb9a59594557:~/php-src# git log -1
    commit e257c086bb22489875e378cb452b925dc3b08bc2 (HEAD -> PHP-8.4, origin/PHP-8.4)
    Author: David Carlier <[email protected]>
    Date:   Fri Mar 13 16:28:59 2026 +0000
    
        ext/gd: phpinfo() to be able to display libjpeg 10.0 support.
        
        Fix #21431
        
        Co-Authored-By: rainerjung
        
        close GH-21432
    
    root@bb9a59594557:~/php-src# cd ext/opcache/jit/ir/ && git log -1
    commit 7fed7999743ba6a5ffc5535e786725d5577f6f34 (HEAD -> master, origin/master, origin/HEAD)
    Author: Dmitry Stogov <[email protected]>
    Date:   Thu Mar 12 19:51:03 2026 +0300
    
        Use general iterative Reverse Post Oprdering algorithm
    
    
    root@bb9a59594557:~/php-src/ext/opcache/jit/ir# cd /app && vendor/bin/psalm test/tests/unit/UuidTest.php
    
    Running on PHP 8.4.20-dev, Psalm 6.15.1@28dc127af1b5aecd52314f6f645bafc10d0e11f9.
    
    JIT acceleration: ON
    
    JIT compilation in progress... Done.
    
    Target PHP version: 8.4 (inferred from current PHP version) Enabled extensions: geos, simplexml (unsupported extensions: ftp).
    
    
    Scanning files...
    
    1012 / 1012...
    
    Analyzing files...
    
    ░
    
    ERROR: InvalidAttribute - test/tests/unit/UuidTest.php:41:4 - Attribute DataProvider cannot be used on a function (see https://psalm.dev/242)
            #[DataProvider('getUuidFormats')]
    
  3. githrdw commented on Mar 16, 2026

    @githrdw

    @ndossche when JIT is enabled, passing an if-shorthand referencing to Attribute constants returns not the expected value somehow.

    See:
    vimeo/psalm#11723 (comment)

  4. jwage commented on Mar 16, 2026

    @jwage

    I am getting the same thing running psalm in github actions with 8.4.19 as well as a segfault when running phpunit tests. It doesn't happen in 8.4.18 but started happening in 8.4.19

  5. jorgsowa commented on Mar 16, 2026

    @jorgsowa
    ContributorAuthor

    Can you try with the fix linked from #21395 ?

    @ndossche, it's merged to master, but it doesn't resolve. I will try to find a minimal reproducer for the issue.

  6. danog commented on Mar 17, 2026

    @danog
    Contributor

    I merged a fix that manages to bypass the attribute-specific issue in vimeo/psalm@69763af

    However, there are still several other JIT bugs that make psalm unusable with JIT right now, as can be reproduced by simply running psalm on the master branch without JIT (no issues) an with JIT (via --force-jit, a bunch of issues).

  7. self-assigned this
    on Mar 25, 2026
  8. arnaud-lb commented on Mar 25, 2026

    @arnaud-lb
    Member

    First bad commit reproducing vimeo/psalm#11723: dd9421d.
    First bad commit in dstogov/ir: dstogov/ir@802947c

    Simplified reproducer:

    // php -n -d zend_extension=$(pwd)/modules/opcache.so -d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.jit=1205 test.php
    
    if (time() > 0) {
        function f2($target) {
            var_dump($target);
        }
    }
    
    function f($storage) {
        f2($storage instanceof DateTime ? Attribute::TARGET_METHOD : Attribute::TARGET_FUNCTION);
    }
    
    f(new DateTime);
  9. removed their assignment
    on Mar 25, 2026
  10. SatoshiFujinaga commented on Mar 31, 2026

    @SatoshiFujinaga

    I'm experiencing the same issue with PHPStan + nikic/php-parser's NodeTraverser.

    Environment

    • PHP 8.5.4 (ZTS)
    • PHPStan 2.1.43 (phar)
    • nikic/php-parser v5.7.0

    Symptom

    NodeTraverser::traverseNode() has an instanceof guard that is bypassed by JIT:

    protected function traverseNode(Node $node): void {
        foreach ($node->getSubNodeNames() as $name) {
            $subNode = $node->{$name};
            if (is_array($subNode)) { ... continue; }
            if (!$subNode instanceof Node) {
                continue;  // ← JIT breaks this guard
            }
            // ...
            $this->traverseNode($subNode);  // ← receives int, throws TypeError
        }
    }

    Error:

    PhpParser\NodeTraverser::traverseNode(): Argument #1 ($node) must be of type PhpParser\Node, int given
    

    The int value is a flags property (e.g., ClassMethod::$flags = 2) which should be filtered by the instanceof guard.

    Verification

    • php -d opcache.jit=0 vendor/bin/phpstan analyse → works correctly, no errors
    • JIT enabled (default) → TypeError as described above

    This matches the same COND instruction optimization bug identified in this issue.

  11. arnaud-lb commented on Apr 3, 2026

    @arnaud-lb
    Member

    This should be fixed in PHP-8.4, 8.5, master now.

    Could you confirm?

  12. jorgsowa commented on Apr 3, 2026

    @jorgsowa
    ContributorAuthor

    I checked on master with an buggy version of Psalm, and I confirm that the bug has been fixed for me. Thank you

  13. added a commit that references this issue on Apr 8, 2026
    d1512d3
  14. arnaud-lb commented on Apr 8, 2026

    @arnaud-lb
    Member

    Thank you @jorgsowa!

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