1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Treat func_get_args as using function params

This commit is contained in:
Matt Brown 2020-09-30 13:08:01 -04:00 committed by Daniil Gentili
parent 63953d5676
commit a6e3d46d62
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 44 additions and 5 deletions

View File

@ -110,6 +110,13 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
*/ */
public $inferred_has_mutation = false; public $inferred_has_mutation = false;
/**
* Holds param nodes for functions with func_get_args calls
*
* @var array<string, ControlFlowNode>
*/
public $param_nodes = [];
/** /**
* @var FunctionLikeStorage * @var FunctionLikeStorage
*/ */
@ -1231,6 +1238,10 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
); );
} }
if ($storage->variadic) {
$this->param_nodes += [$param_assignment->id => $param_assignment];
}
$var_type->parent_nodes += [$param_assignment->id => $param_assignment]; $var_type->parent_nodes += [$param_assignment->id => $param_assignment];
} }

View File

@ -285,6 +285,7 @@ class ArgumentAnalyzer
if (!$arg_type_param) { if (!$arg_type_param) {
$arg_type_param = Type::getMixed(); $arg_type_param = Type::getMixed();
$arg_type_param->parent_nodes = $arg_type->parent_nodes;
} }
} }
@ -1329,11 +1330,9 @@ class ArgumentAnalyzer
$statements_analyzer->control_flow_graph->addSink($sink); $statements_analyzer->control_flow_graph->addSink($sink);
} }
if ($input_type->parent_nodes) { foreach ($input_type->parent_nodes as $parent_node) {
foreach ($input_type->parent_nodes as $parent_node) { $statements_analyzer->control_flow_graph->addNode($method_node);
$statements_analyzer->control_flow_graph->addNode($method_node); $statements_analyzer->control_flow_graph->addPath($parent_node, $argument_value_node, 'arg');
$statements_analyzer->control_flow_graph->addPath($parent_node, $argument_value_node, 'arg');
}
} }
if ($function_param->assert_untainted) { if ($function_param->assert_untainted) {

View File

@ -1515,6 +1515,22 @@ class FunctionCallAnalyzer extends CallAnalyzer
$statements_analyzer->node_data->setType($stmt, $arr_type); $statements_analyzer->node_data->setType($stmt, $arr_type);
} }
} }
} elseif ($function_name->parts === ['func_get_args']) {
$source = $statements_analyzer->getSource();
if ($statements_analyzer->control_flow_graph
&& $source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
) {
if ($statements_analyzer->control_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph) {
foreach ($source->param_nodes as $param_node) {
$statements_analyzer->control_flow_graph->addPath(
$param_node,
new ControlFlowNode('variable-use', 'variable use', null),
'variable-use'
);
}
}
}
} elseif (strtolower($function_name->parts[0]) === 'var_dump' } elseif (strtolower($function_name->parts[0]) === 'var_dump'
|| strtolower($function_name->parts[0]) === 'shell_exec') { || strtolower($function_name->parts[0]) === 'shell_exec') {
if (IssueBuffer::accepts( if (IssueBuffer::accepts(

View File

@ -2174,6 +2174,19 @@ class UnusedVariableTest extends TestCase
print_r($source); print_r($source);
}' }'
], ],
'implicitSpread' => [
'<?php
function validate(bool $b, bool $c) : void {
$d = [$b, $c];
print_r(...$d);
}'
],
'funcGetArgs' => [
'<?php
function validate(bool $b, bool $c) : void {
print_r(...func_get_args());
}'
],
]; ];
} }