Skip to content

zend_ast: Fix FCC in trait const expressions resolving to the first using class - #25083

Closed
jorgsowa wants to merge 2 commits into
php:PHP-8.5from
jorgsowa:fix-fcc-const-expr-trait-cache
Closed

jorgsowa wants to merge 2 commits into
php:PHP-8.5from
jorgsowa:fix-fcc-const-expr-trait-cache

Conversation

@jorgsowa

Copy link
Copy Markdown
Contributor

The resolved method was cached on the shared AST node, so self::/parent:: and visibility were only checked for the first class evaluating it.

@jorgsowa jorgsowa self-assigned this Oct 31, 2026

@iliaal iliaal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, 2 nits aside.

Comment thread Zend/zend_ast.c

ZEND_MAP_PTR_SET(fcc_ast->fptr, fptr);
/* The AST may be shared between scopes (e.g. via traits), so only cache scope-independent results. */
if ((ast->child[0]->attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT) == ZEND_FETCH_CLASS_DEFAULT

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also disables caching for self::/parent:: and non-public FCC in non-trait default args, where the AST isn't shared and the scope is fixed, so those re-resolve the method on every default-arg evaluation. Correct as a simple fix, but worth a sentence in the description: narrowing it to only shared (trait) ASTs isn't cheap to detect at this point.

<?php

trait T {
public static function make($f = A::who(...)) { return $f(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a case for the branch that still caches across scopes? A trait with a named public-method default (A::who(...)) used by two classes, both returning A. 005 covers named+private; the named+public cached path isn't exercised.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. test case added.

The resolved method was cached on the shared AST node, so self::/parent::
and visibility were only checked for the first class evaluating it.
@jorgsowa
jorgsowa force-pushed the fix-fcc-const-expr-trait-cache branch from cb0f70b to c4fa1c9 Compare November 1, 2026 20:43
@jorgsowa jorgsowa closed this in 44a2a2c Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants