Skip to content
17 changes: 17 additions & 0 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
use PHPStan\Parser\ImmediatelyInvokedClosureVisitor;
use PHPStan\Parser\LineAttributesVisitor;
use PHPStan\Parser\Parser;
use PHPStan\Php\PhpVersion;
use PHPStan\PhpDoc\PhpDocInheritanceResolver;
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
use PHPStan\PhpDoc\Tag\VarTag;
Expand Down Expand Up @@ -862,9 +863,25 @@ public function processStmtNode(
$hasYield = false;
$throwPoints = [];
$isAlwaysTerminating = false;
$phpVersion = $this->container->getByType(PhpVersion::class);
foreach ($stmt->exprs as $echoExpr) {
$result = $this->processExprNode($stmt, $echoExpr, $scope, $storage, $nodeCallback, ExpressionContext::createDeep());
$throwPoints = array_merge($throwPoints, $result->getThrowPoints());
if ($phpVersion->throwsOnStringCast()) {
$exprType = $scope->getType($echoExpr);
$toStringMethod = $scope->getMethodReflection($exprType, '__toString');
if ($toStringMethod !== null) {
$toStringResult = $this->processExprNode(
$stmt,
new Expr\MethodCall($echoExpr, new Identifier('__toString')),
$scope,
new ExpressionResultStorage(),
new NoopNodeCallback(),
ExpressionContext::createDeep(),
);
$throwPoints = array_merge($throwPoints, $toStringResult->getThrowPoints());
}
}
$scope = $result->getScope();
$hasYield = $hasYield || $result->hasYield();
$isAlwaysTerminating = $isAlwaysTerminating || $result->isAlwaysTerminating();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,4 +748,18 @@ public function testBug13806(): void
]);
}

public function testBug5952(): void
{
$this->analyse([__DIR__ . '/data/bug-5952.php'], [
[
'Dead catch - Exception is never thrown in the try block.',
51,
],
[
'Dead catch - Exception is never thrown in the try block.',
57,
],
]);
}

}
59 changes: 59 additions & 0 deletions tests/PHPStan/Rules/Exceptions/data/bug-5952.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php // lint >= 7.4

namespace Bug5952;

class Foo
{
public function __toString(): string
{
throw new \Exception();
}
}

$foo = new Foo();

try {
echo $foo;
} catch (\Exception $e) {
echo "Should be printed";
}

class Bar
{
/** @throws \Exception */
public function __toString(): string
{
throw new \Exception();
}
}

$bar = new Bar();

try {
echo $bar;
} catch (\Exception $e) {
echo "Should be printed";
}

class Baz
{
/** @throws void */
public function __toString(): string
{
return 'hello';
}
}

$baz = new Baz();

try {
echo $baz;
} catch (\Exception $e) {
echo "Should not be printed";
}

try {
echo 123;
} catch (\Exception $e) {
echo "Should not be printed";
}
Loading