Skip to content

Commit

Permalink
Fix segfault using pipe type hint with first item as null (#1102)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkornaukhov03 authored Sep 14, 2024
1 parent 3ce70ae commit a0a7b38
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
11 changes: 7 additions & 4 deletions compiler/class-assumptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,15 @@ ClassPtr Assumption::extract_instance_from_type_hint(const TypeHint *a) {
// between them, so we can call a more expensive get_common_base_or_interface() method here;
// the method below is somewhat conservative, but it's good enough in the usual cases
ClassPtr result;
ClassPtr first = as_pipe->items[0]->try_as<TypeHintInstance>()->resolve();
for (int i = 1; i < as_pipe->items.size(); ++i) {
if (as_pipe->items[i]->try_as<TypeHintPrimitive>()) {
ClassPtr first;
for (const auto *item : as_pipe->items) {
if (item->try_as<TypeHintPrimitive>()) {
continue; // we know that it's tp_Null
}
ClassPtr other = extract_instance_from_type_hint(as_pipe->items[i]);
if (!first) {
first = item->try_as<TypeHintInstance>()->resolve();
}
ClassPtr other = extract_instance_from_type_hint(item);
const auto common_bases = first->get_common_base_or_interface(other);
if (common_bases.size() != 1) {
return ClassPtr{};
Expand Down
32 changes: 32 additions & 0 deletions tests/phpt/typehints/return_types/16_null_first_in_pipe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@ok
<?php

class BaseClass {
public function call(): void {}
}

class ChildClass1 extends BaseClass {}
class ChildClass2 extends BaseClass {}

/** @return null|ChildClass1|ChildClass2 */
function execute() {
return new ChildClass1();
}

/** @return null|ChildClass1|null|ChildClass2 */
function execute2() {
return new ChildClass2();
}

/** @return null|null|null */
function execute3() {
return null;
}

function main(): void {
execute()->call();
execute2()->call();
var_dump(execute3());
}

main();

0 comments on commit a0a7b38

Please sign in to comment.