Skip to content

Language: asymmetric visibility — public+private(set)/public+protected(set) must compile fatal (zend_compile.c) #7099

Description

@PurHur

Category

language

Problem

PHP 8.4 asymmetric property visibility allows only private(set) or protected(set) on a property — not combined with an explicit get visibility modifier (public, protected, or private). Zend rejects invalid combos at compile time:

Multiple access type modifiers are not allowed

This compiler accepts invalid declarations such as public private(set) and public protected(set), then runs user code. That diverges from php-src and lets illegal APIs ship.

php-src-strict: valid private(set) string $x (get public by default) must continue to work; this issue is invalid modifier pairs only.

php-src reference

Repro (failure today)

repro-asymmetric-modifiers.php:

<?php
class A { public private(set) string $x = 'a'; }
echo "compiled\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php bin/vm.php repro-asymmetric-modifiers.php; echo vm_exit=$?
php -l repro-asymmetric-modifiers.php; echo zend_parse=$?
'
Case Zend This compiler (2026-06-06)
public private(set) string $x parse/compile fatal compiles, prints compiled
public protected(set) string $x parse/compile fatal compiles, prints compiled
private(set) string $x OK OK (out of scope)

Scope (this repo)

Area Path
Parser / php-cfg reject or flag double visibility in property declaration
Compiler lib/Compiler.php — asymmetricSetVisibilityFromCfgOp / property declare: fatal if get visibility + (set) modifier both explicit
Preprocessor lib/SourcePreprocessor/PropertyHooks.php if hooks rewrite modifiers
Tests test/compliance/cases/language/asymmetric_visibility_invalid_modifiers.phpt (VM + JIT lint + AOT lint)

PHP-in-PHP: compile-time guard in lib/; no new runtime/*.c branches.

Done when

  • Both repro classes fail compile with Zend-equivalent message before user code runs
  • Valid private(set) / protected(set) without extra get modifier still compile
  • ./script/ci-fast.sh --filter asymmetric_visibility_invalid_modifiers green on VM
  • bin/jit.php --lint and bin/compile.php --lint on the PHPT case exit non-zero

Related

Activity

  1. added
    enhancementNew feature or request
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jun 6, 2026
  2. PurHur commented on Jun 6, 2026

    @PurHur
    OwnerAuthor

    claim: worker-lane-b — starting this run

  3. PurHur commented on Jun 6, 2026

    @PurHur
    OwnerAuthor

    Merged via #7106.

    Fix: AsymmetricVisibilityRewriter::rejectExplicitReadBeforeAsymmetricSetModifier() rejects explicit get visibility combined with (set) (e.g. public private(set), public protected(set), public (private(set))) at compile time with Zend's Multiple access type modifiers are not allowed.

    Verification:

    ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
    php bin/vm.php -r "class A { public private(set) string \$x = \"a\"; }" 2>&1; echo vm_exit=\$?
    vendor/bin/phpunit --filter asymmetric_visibility
    '

    → compile fatal (vm_exit=255); 21/21 asymmetric visibility tests OK.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:compilerCompiler / CFG / JITarea:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions