fix: call mark_as_used() for classes referenced only in instanceof (#68)#1561
Open
KorsarOfficial wants to merge 1 commit intoVKCOM:masterfrom
Open
fix: call mark_as_used() for classes referenced only in instanceof (#68)#1561KorsarOfficial wants to merge 1 commit intoVKCOM:masterfrom
KorsarOfficial wants to merge 1 commit intoVKCOM:masterfrom
Conversation
…KCOM#68) When a class appeared only in an `instanceof` expression and was never instantiated anywhere else, the code-gen pass tried to include its generated header but the header had never been written, causing a crash. The fix mirrors the identical pattern already applied to `op_catch`: call `mark_as_used()` so the class header gets generated even when the class is never used as a value. Also adds two regression tests: - tests/phpt/interfaces/135_instanceof_unused_class.php - tests/phpt/interfaces/136_instanceof_only_in_condition.php
Contributor
|
Why open a new thread when there’s already #1557? Apart from the fact that you’ve removed the use of |
Author
|
Hey, fair point. I've been experimenting with Claude as a coding assistant recently — it ended up as a co-author in the commits by default, and I didn't notice until after the PRs were already up. Didn't want that showing up in upstream history, so I cleaned it up and reopened. Sorry for the noise. The code changes are the same, just without the AI attribution in the commit metadata. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a class
Cappears only in aninstanceofexpression and is never instantiated or used as a value, the code-gen pass crashes: it emits an#includeforC's header, but the header was never generated becausemark_as_used()was never called forC.Formal Analysis
Define the class dependency system:
C = {c₁, c₂, …, cₙ}— set of all classesU(c)— predicate: class is marked as "used"H(c)— predicate: header file was generatedR(c)— predicate: class is referenced in code-gen outputCode-gen invariant:
∀c ∈ C : R(c) ⟹ H(c)Header rule:
H(c) ⟺ U(c)Required invariant:
∀c ∈ C : R(c) ⟹ U(c)The existing
mark_as_used()calls cover instantiation,catch, type hints, and value references — but notinstanceof. Wheninstanceofis the only reference,U(c) = falsewhileR(c) = true, violating the invariant.Fix
Add
mark_as_used()forop_instanceofinCalcFuncDepPass::on_enter_vertex, mirroring the identical pattern forop_catch.Correctness:
U'(c) = U(c) ∨ instanceof_ref(c)⟹∀c : R(c) ⟹ U'(c) ⟹ H(c). ∎Complexity: O(1) per instanceof vertex — negligible overhead.
Tests
tests/phpt/interfaces/135_instanceof_unused_class.php— basic regressiontests/phpt/interfaces/136_instanceof_only_in_condition.php— instanceof only in conditional branchTechnical Report
📄 Full report with mathematical formalization (PDF)
Closes #68