Skip to content

The influence of opcache on the behavior of enum cases. #8418

Closed

Description

@SerafimArts

Description

The following code:

<?php

class ExampleClass
{
    public const EXAMPLE_CONST = 42;
}

enum ExampleEnum: int
{
    case ENUM_CASE = ExampleClass::EXAMPLE_CONST;
}

var_dump(ExampleEnum::ENUM_CASE->value);

Resulted in this output:

$ php test.php -dopcache.jit_buffer_size=0 -dopcache.enable=1 -dopcache.enable_cli=0
// - First execution: 42
// - Second execution: 42
// - Third execution: 42

$ php test.php -dopcache.jit_buffer_size=0 -dopcache.enable=1 -dopcache.enable_cli=1
// - First execution: 42
// - Second execution: Enum case value must be compile-time evaluatable
// - Third execution: Enum case value must be compile-time evaluatable

But I expected this output instead:

// - First execution: 42
// - Second execution: 42
// - Third execution: 42

Conclusion

  • Behavior is affected by enabling or disabling opcache.
  • The jit buffer is disabled, which disables JIT compilation and therefore the problem occurs at an earlier "compilation stage".

Environment

Linux (Debian-based)

PHP 8.1.4 (cli) (built: Apr  4 2022 13:30:33) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.4, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.4, Copyright (c), by Zend Technologies

Other Info

  1. Perhaps the issue has been resolved by Allow arbitrary const expressions in backed enums #8190
  2. This issue has been moved from another Can't use inherited constant value via 'self' in enum case value #7821

PHP Version

8.1.4

Operating System

Ubuntu Budgie 21.10

Activity

  1. nikic commented on Apr 24, 2022

    @nikic
    Member

    We should probably set ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION while evaluating the enum value to avoid the discrepancy with and without opcache (by always making it an error).

  2. SerafimArts commented on Apr 24, 2022

    @SerafimArts
    ContributorAuthor

    by always making it an error

    Hmmm.... Aren't class constants compile time instructions? It seems the other way around, it shouldn't throw any errors.

  3. nikic commented on Apr 24, 2022

    @nikic
    Member

    Making this actually work requires #8190, i.e. support for evaluating the constant expression at runtime. It's not technically possible to evaluate a constant reference at compile-time if opcache is used (in the general case where the constant is defined in a different file). The only thing we can do in a patch release is to consistently forbid this.

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