@@ -23,43 +23,52 @@ class NonVolatileConstIntegralOrEnumType extends IntegralOrEnumType {
2323}
2424
2525/**
26- * Holds if declaration `innerDecl`, declared in a lambda, hides a declaration `outerDecl` captured by the lambda.
26+ * Holds if declaration `innerDecl`, declared in a lambda, hides a declaration `outerDecl` by the lambda.
2727 */
2828predicate hiddenInLambda ( UserVariable outerDecl , UserVariable innerDecl ) {
29- exists ( Scope s , Closure le |
30- //innerDecl declared inside of the lambda
31- s .getADeclaration ( ) = innerDecl and
32- s .getAnAncestor ( ) = le and
33- //a variable can be accessed (therefore hide) another when:
34- //it is explicitly captured
29+ exists (
30+ Scope innerScope , LambdaExpression lambdaExpr , Scope lambdaExprScope , Scope outerScope ,
31+ Closure lambdaClosure
32+ |
33+ // The variable `innerDecl` is declared inside of the lambda.
34+ innerScope .getADeclaration ( ) = innerDecl and
35+ // Because a lambda is compiled down to a closure, we need to use the closure to determine if the declaration
36+ // is part of the lambda.
37+ innerScope .getAnAncestor ( ) = lambdaClosure and
38+ // Next we determine the scope of the lambda expression to determine if `outerDecl` is visible in the scope of the lambda.
39+ lambdaClosure .getLambdaExpression ( ) = lambdaExpr and
40+ lambdaExprScope .getAnExpr ( ) = lambdaExpr and
41+ outerScope .getADeclaration ( ) = outerDecl and
42+ lambdaExprScope .getStrictParent * ( ) = outerScope and
3543 (
44+ // A definition can be hidden if it is in scope and it is captured by the lambda,
3645 exists ( LambdaCapture cap |
37- outerDecl .getAnAccess ( ) = cap .getInitializer ( ) .( VariableAccess ) and
38- le .getLambdaExpression ( ) .getACapture ( ) = cap and
39- //captured variable (outerDecl) is in the same (function) scope as the lambda itself
40- outerDecl .getParentScope ( ) = le .getEnclosingFunction ( ) .getBasicBlock ( ) .( Scope )
46+ lambdaExpr .getACapture ( ) = cap and
47+ // The outer declaration is captured by the lambda
48+ outerDecl .getAnAccess ( ) = cap .getInitializer ( )
4149 )
4250 or
43- //is non-local
51+ // it is is non-local,
4452 outerDecl instanceof GlobalVariable
4553 or
46- //has static or thread local storage duration
54+ // it has static or thread local storage duration,
4755 ( outerDecl .isThreadLocal ( ) or outerDecl .isStatic ( ) )
4856 or
49- //is a reference that has been initialized with a constant expression.
57+ //it is a reference that has been initialized with a constant expression.
5058 outerDecl .getType ( ) .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
5159 exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
5260 or
53- //const non-volatile integral or enumeration type and has been initialized with a constant expression
61+ //it const non-volatile integral or enumeration type and has been initialized with a constant expression
5462 outerDecl .getType ( ) instanceof NonVolatileConstIntegralOrEnumType and
5563 exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
5664 or
57- //is constexpr and has no mutable members
65+ //it is constexpr and has no mutable members
5866 outerDecl .isConstexpr ( ) and
5967 not exists ( Class c |
6068 c = outerDecl .getType ( ) and not c .getAMember ( ) instanceof MutableVariable
6169 )
6270 ) and
71+ // Finally, the variables must have the same names.
6372 innerDecl .getName ( ) = outerDecl .getName ( )
6473 )
6574}
0 commit comments