Skip to content

Fix phpstan/phpstan#6799: wrongly reported empty array#5206

Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-c5gzxk3
Open

Fix phpstan/phpstan#6799: wrongly reported empty array#5206
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-c5gzxk3

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

When a variable is passed by reference inside an array literal (e.g., [&$whereFilter, ...]) and that array is passed to a function like call_user_func_array, PHPStan incorrectly retained the variable's initial precise type (e.g., array{} for an empty array). This caused false positives such as "Comparison operation > between 0 and 0 is always false" because PHPStan didn't recognize the variable could be modified through the reference.

Changes

  • Modified src/Analyser/ExprHandler/ArrayHandler.php to assign MixedType to variables used in by-reference array items ($arrayItem->byRef), widening their type since a reference is created that could be used to modify the variable
  • Added regression test tests/PHPStan/Analyser/nsrt/bug-6799.php that reproduces the original issue with call_user_func_array and a by-reference array parameter

Root cause

The ArrayHandler::processExpr method did not handle the byRef flag on ArrayItem nodes. When processing [&$var, ...], the referenced variable's type remained unchanged in the scope. This meant that after $whereFilter = array() followed by call_user_func_array([$this, 'method'], [&$whereFilter, ...]), PHPStan still considered $whereFilter to be array{} (empty array), leading to false positives about count($whereFilter) > 0 being always false.

The fix follows the same pattern used for foreach by-reference (foreach ($arr as &$val)), which assigns MixedType to the referenced variable since it can be modified through the reference.

Test

Added tests/PHPStan/Analyser/nsrt/bug-6799.php which reproduces the original issue: a class method that uses call_user_func_array with a by-reference variable inside the argument array. The test asserts that the variable's type is widened to mixed after the reference is created, rather than remaining as array{}.

Fixes phpstan/phpstan#6799

- Widen variable type to mixed when passed by reference inside an array literal ([&$var, ...])
- This fixes false positives like "Comparison operation > between 0 and 0 is always false" when variables are passed by reference through call_user_func_array
- Added regression test in tests/PHPStan/Analyser/nsrt/bug-6799.php
- The root cause was that ArrayHandler did not account for byRef array items, so PHPStan retained the initial precise type (e.g. array{}) even after a reference was created

Closes phpstan/phpstan#6799
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant