@@ -42,7 +42,16 @@ private Element getParentScope(Element e) {
4242 then result = e .getParentScope ( )
4343 else (
4444 // Statements do no have a parent scope, so return the enclosing block.
45- result = e .( Stmt ) .getEnclosingBlock ( ) or result = e .( Expr ) .getEnclosingBlock ( )
45+ result = e .( Stmt ) .getEnclosingBlock ( )
46+ or
47+ result = e .( Expr ) .getEnclosingBlock ( )
48+ or
49+ // Catch block parameters don't have an enclosing scope, so attach them to the
50+ // the block itself
51+ exists ( CatchBlock cb |
52+ e = cb .getParameter ( ) and
53+ result = cb
54+ )
4655 )
4756}
4857
@@ -209,7 +218,42 @@ private predicate hides_candidateStrict(UserVariable v1, UserVariable v2) {
209218 v2 = getPotentialScopeOfVariableStrict ( v1 ) and
210219 v1 .getName ( ) = v2 .getName ( ) and
211220 // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
212- not ( v1 .isMember ( ) or v2 .isMember ( ) )
221+ not ( v1 .isMember ( ) or v2 .isMember ( ) ) and
222+ (
223+ // If v1 is a local variable, ensure that v1 is declared before v2
224+ (
225+ v1 instanceof LocalVariable and
226+ // Ignore variables declared in conditional expressions, as they apply to
227+ // the nested scope
228+ not v1 = any ( ConditionDeclExpr cde ) .getVariable ( ) and
229+ // Ignore variables declared in loops
230+ not exists ( Loop l | l .getADeclaration ( ) = v1 )
231+ )
232+ implies
233+ exists ( BlockStmt bs , DeclStmt v1Stmt , Stmt v2Stmt |
234+ v1 = v1Stmt .getADeclaration ( ) and
235+ getEnclosingStmt ( v2 ) .getParentStmt * ( ) = v2Stmt
236+ |
237+ bs .getIndexOfStmt ( v1Stmt ) <= bs .getIndexOfStmt ( v2Stmt )
238+ )
239+ )
240+ }
241+
242+ /**
243+ * Gets the enclosing statement of the given variable, if any.
244+ */
245+ private Stmt getEnclosingStmt ( LocalScopeVariable v ) {
246+ result .( DeclStmt ) .getADeclaration ( ) = v
247+ or
248+ exists ( ConditionDeclExpr cde |
249+ cde .getVariable ( ) = v and
250+ result = cde .getEnclosingStmt ( )
251+ )
252+ or
253+ exists ( CatchBlock cb |
254+ cb .getParameter ( ) = v and
255+ result = cb .getEnclosingStmt ( )
256+ )
213257}
214258
215259/** Holds if `v2` hides `v1`. */
0 commit comments