diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 4f0b2f6536..20e9898aa7 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -2384,10 +2384,22 @@ static function () use ($expr, $rightResult): MutatingScope { $hasYield = false; $throwPoints = []; if ($expr->class instanceof Expr) { + $objectClasses = TypeUtils::getDirectClassNames($scope->getType($expr)); + if (count($objectClasses) === 1) { + $objectExprResult = $this->processExprNode(new New_(new Name($objectClasses[0])), $scope, static function (): void { + }, $context->enterDeep()); + $additionalThrowPoints = $objectExprResult->getThrowPoints(); + } else { + $additionalThrowPoints = [ThrowPoint::createImplicit($scope)]; + } + $result = $this->processExprNode($expr->class, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); + foreach ($additionalThrowPoints as $throwPoint) { + $throwPoints[] = $throwPoint; + } } elseif ($expr->class instanceof Class_) { $this->reflectionProvider->getAnonymousClassReflection($expr->class, $scope); // populates $expr->class->name $this->processStmtNode($expr->class, $scope, $nodeCallback); diff --git a/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php b/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php index 80f1d7c3a4..f4898e44ed 100644 --- a/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php +++ b/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php @@ -54,4 +54,18 @@ public function testRule(): void ]); } + public function testBug4806(): void + { + $this->analyse([__DIR__ . '/data/bug-4806.php'], [ + [ + 'Dead catch - ArgumentCountError is never thrown in the try block.', + 65, + ], + [ + 'Dead catch - Throwable is never thrown in the try block.', + 119, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Exceptions/data/bug-4806.php b/tests/PHPStan/Rules/Exceptions/data/bug-4806.php new file mode 100644 index 0000000000..78d1ae5d38 --- /dev/null +++ b/tests/PHPStan/Rules/Exceptions/data/bug-4806.php @@ -0,0 +1,124 @@ + $class + */ + function createNeverThrows(string $class): object + { + try { + $object = new $class(); + } catch (\ArgumentCountError $throwable) { + + } + + return $object; + } + + /** + * @param class-string $class + */ + function createMayThrowArgumentCountError(string $class): object + { + try { + $object = new $class(); + } catch (\ArgumentCountError $error) { + + } + + return $object; + } + + /** + * @param class-string $class + */ + function createMayThrowArgumentCountErrorB(string $class): object + { + try { + $object = new $class(); + } catch (\Throwable $throwable) { + + } + + return $object; + } + + /** + * @param class-string $class + */ + function implicitThrow(string $class): void + { + try { + $object = new $class(); + } catch (\Throwable $throwable) { + + } + } + + /** + * @param class-string $class + */ + function hasNoConstructor(string $class): void + { + try { + $object = new $class(); + } catch (\Throwable $throwable) { + + } + } + +}