@@ -49,6 +49,7 @@ class VariableInfo {
4949 */
5050 public $ scopeType ;
5151 public $ typeHint ;
52+ public $ passByReference = false ;
5253 public $ firstDeclared ;
5354 public $ firstInitialized ;
5455 public $ firstRead ;
@@ -731,6 +732,13 @@ protected function checkForFunctionPrototype(
731732 ($ tokens [$ functionPtr ]['code ' ] === T_CLOSURE ))) {
732733 // TODO: typeHint
733734 $ this ->markVariableDeclaration ($ varName , 'param ' , null , $ stackPtr , $ functionPtr );
735+ // Are we pass-by-reference?
736+ $ referencePtr = $ phpcsFile ->findPrevious (T_WHITESPACE ,
737+ $ stackPtr - 1 , null , true , null , true );
738+ if (($ referencePtr !== false ) && ($ tokens [$ referencePtr ]['code ' ] === T_BITWISE_AND )) {
739+ $ varInfo = $ this ->getVariableInfo ($ varName , $ functionPtr );
740+ $ varInfo ->passByReference = true ;
741+ }
734742 // Are we optional with a default?
735743 if ($ this ->isNextThingAnAssign ($ phpcsFile , $ stackPtr ) !== false ) {
736744 $ this ->markVariableAssignment ($ varName , $ stackPtr , $ functionPtr );
@@ -1329,6 +1337,13 @@ protected function processScopeClose(
13291337 if ($ varInfo ->ignoreUnused || isset ($ varInfo ->firstRead )) {
13301338 continue ;
13311339 }
1340+ if ($ varInfo ->passByReference && isset ($ varInfo ->firstInitialized )) {
1341+ // If we're pass-by-reference then it's a common pattern to
1342+ // use the variable to return data to the caller, so any
1343+ // assignment also counts as "variable use" for the purposes
1344+ // of "unused variable" warnings.
1345+ continue ;
1346+ }
13321347 if (isset ($ varInfo ->firstDeclared )) {
13331348 $ phpcsFile ->addWarning (
13341349 "Unused %s %s. " ,
0 commit comments