@@ -23,43 +23,52 @@ class NonVolatileConstIntegralOrEnumType extends IntegralOrEnumType {
23
23
}
24
24
25
25
/**
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.
27
27
*/
28
28
predicate 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
35
43
(
44
+ // A definition can be hidden if it is in scope and it is captured by the lambda,
36
45
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 ( )
41
49
)
42
50
or
43
- //is non-local
51
+ // it is is non-local,
44
52
outerDecl instanceof GlobalVariable
45
53
or
46
- //has static or thread local storage duration
54
+ // it has static or thread local storage duration,
47
55
( outerDecl .isThreadLocal ( ) or outerDecl .isStatic ( ) )
48
56
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.
50
58
outerDecl .getType ( ) .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
51
59
exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
52
60
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
54
62
outerDecl .getType ( ) instanceof NonVolatileConstIntegralOrEnumType and
55
63
exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
56
64
or
57
- //is constexpr and has no mutable members
65
+ //it is constexpr and has no mutable members
58
66
outerDecl .isConstexpr ( ) and
59
67
not exists ( Class c |
60
68
c = outerDecl .getType ( ) and not c .getAMember ( ) instanceof MutableVariable
61
69
)
62
70
) and
71
+ // Finally, the variables must have the same names.
63
72
innerDecl .getName ( ) = outerDecl .getName ( )
64
73
)
65
74
}
0 commit comments