Skip to content

ConstructorExecutionTransformer rewrites new inside constant expressions (fatal on load) #603

Description

@lisachenko

Summary

With Features::INTERCEPT_INITIALIZATIONS enabled, ConstructorExecutionTransformer rewrites every New_ node in a file — including new in initializers (PHP 8.1): parameter defaults, static variable initializers, and attribute arguments. A method call is not a valid constant expression, so the transformed file is a compile-time fatal.

Found during the PHP 8.5 support audit (PR #597). Reproduces on PHP 8.4 / 8.5.10 / 8.6.0beta2.

Reproduction

Input (tests/Fixtures/audit/src/Php81NewInInitializers.php):

public function run(Collaborator $helper = new Collaborator('method-default')): string
{
    static $memo = new \ArrayObject();
    ...

Transformed output:

public function run(Collaborator $helper = \Go\Instrument\Transformer\ConstructorExecutionTransformer::getInstance()->{Collaborator::class}('method-default')): string
{
    static $memo = \Go\Instrument\Transformer\ConstructorExecutionTransformer::getInstance()->{\ArrayObject::class}();
PHP Fatal error: Constant expression contains invalid operations

Root cause

src/Instrument/Transformer/ConstructorExecutionTransformer.php:60-88 — the FindingVisitor selects all Expr\New_ nodes with no context filter.

Proposed fix

Skip New_ nodes that appear in constant-expression context: while traversing, exclude nodes whose ancestors include Param->default, StaticVar->default, Const_/ClassConst, PropertyItem->default, EnumCase->expr, or Attribute args (a small NodeVisitor tracking these containers, or checking node attributes of the enclosing structure during the finding pass). Such new expressions run inside engine-managed initializer evaluation and cannot be intercepted — document that limitation (they still hit interception when the class itself is woven elsewhere at normal call sites).

Environment

  • goaop/framework master (4.0-dev), PHP 8.4 / 8.5.10 / 8.6.0beta2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions