diff --git a/compiler/pipes/calc-func-dep.cpp b/compiler/pipes/calc-func-dep.cpp index b6adbfa017..5bfdeb7f88 100644 --- a/compiler/pipes/calc-func-dep.cpp +++ b/compiler/pipes/calc-func-dep.cpp @@ -33,6 +33,11 @@ VertexPtr CalcFuncDepPass::on_enter_vertex(VertexPtr vertex) { } if (auto instanceof = vertex.try_as()) { + // mark_as_used() is required here for the same reason as in op_catch below: + // a class used only in instanceof may never be instantiated elsewhere, + // so without this call the code-gen pass would crash trying to include + // a header that was never generated (see #68) + instanceof->derived_class->mark_as_used(); current_function->class_dep.insert(instanceof->derived_class); } diff --git a/tests/phpt/interfaces/135_instanceof_unused_class.php b/tests/phpt/interfaces/135_instanceof_unused_class.php new file mode 100644 index 0000000000..2f064eb3c5 --- /dev/null +++ b/tests/phpt/interfaces/135_instanceof_unused_class.php @@ -0,0 +1,22 @@ +@ok +radius = $r; } +} + +class Square implements Shape { + public float $side; + public function __construct(float $s) { $this->side = $s; } +} + +// Triangle is declared but never instantiated — only appears in instanceof. +class Triangle implements Shape {} + +function describe(Shape $s): string { + if ($s instanceof Circle) return 'circle'; + if ($s instanceof Square) return 'square'; + if ($s instanceof Triangle) return 'triangle'; // Triangle: only in instanceof + return 'unknown'; +} + +var_dump(describe(new Circle(1.0))); // string(6) "circle" +var_dump(describe(new Square(2.0))); // string(6) "square"