phpstan: False positive: Unreachable statement

Bug report

phpstan 0.12 latest

Code snippet that reproduces the problem

	protected function propertyInUse(array $tokens, int $closeTagIndex, string $variable): bool {
		/** @var string $property */
		$property = substr($variable, 1);

		$i = $closeTagIndex + 1;
		while (isset($tokens[$i])) {
			if ($tokens[$i]['code'] !== T_VARIABLE || $tokens[$i]['content'] !== '$this') {
				$i++;
				continue;
			}
			$i++;
			if ($tokens[$i]['code'] !== T_OBJECT_OPERATOR) {
				$i++;
				continue;
			}
			$i++;
			$token = $tokens[$i];
			if ($token['code'] !== T_STRING || $token['content'] !== $property) {
				$i++;
				continue;
			}
			$i++; // 520
			if ($tokens[$i]['code'] !== T_OBJECT_OPERATOR) {
				$i++;
				continue;
			}

			return true;
		}

		return false;
	}

Expected output

  520    Unreachable statement - code above always terminates.  

This is not true.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (14 by maintainers)

Most upvoted comments

The problem was that when the $i in $i++ wasn’t constant string like 1 but a general string like int, no expression including $i was invalidated.

Fixed by adding invalidateExpression to NodeScopeResolver in this situation, and changing MutatingScope::invalidateExpression() to have similar logic to assignVariable(): https://github.com/phpstan/phpstan-src/commit/9665e165d50737c53d68521936cf8ab2f2c07109

Assigning from $i to some new value $j (and asserting on that) fixes the issue: https://phpstan.org/r/0f0d9246-2603-441d-b079-e08c83bed59c

Or rather, @dereuromark I think the example does reproduce the issue (and @ondrejmirtes was just pointing out where the bug takes effect)