@@ -6,11 +6,22 @@ import cpp
6
6
import codingstandards.cpp.Customizations
7
7
import codingstandards.cpp.Exclusions
8
8
import codingstandards.cpp.Scope
9
+ import codingstandards.cpp.ConstHelpers
9
10
10
11
abstract class IdentifierHiddenSharedQuery extends Query { }
11
12
12
13
Query getQuery ( ) { result instanceof IdentifierHiddenSharedQuery }
13
14
15
+ /**
16
+ * a `IntegralOrEnumType` that is nonvolatile and const
17
+ */
18
+ class NonVolatileConstIntegralOrEnumType extends IntegralOrEnumType {
19
+ NonVolatileConstIntegralOrEnumType ( ) {
20
+ not this .isVolatile ( ) and
21
+ this .isConst ( )
22
+ }
23
+ }
24
+
14
25
/**
15
26
* Holds if declaration `innerDecl`, declared in a lambda, hides a declaration `outerDecl` captured by the lambda.
16
27
*/
@@ -19,10 +30,35 @@ predicate hiddenInLambda(UserVariable outerDecl, UserVariable innerDecl) {
19
30
//innerDecl declared inside of the lambda
20
31
s .getADeclaration ( ) = innerDecl and
21
32
s .getAnAncestor ( ) = le and
22
- le .getEnclosingFunction ( ) .getBasicBlock ( ) .( Scope ) = outerDecl .getParentScope ( ) and
23
- exists ( LambdaCapture cap |
24
- outerDecl .getAnAccess ( ) = cap .getInitializer ( ) .( VariableAccess ) and
25
- le .getLambdaExpression ( ) .getACapture ( ) = cap
33
+ //a variable can be accessed (therefore hide) another when:
34
+ //it is explicitly captured
35
+ (
36
+ 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 )
41
+ )
42
+ or
43
+ //is non-local
44
+ outerDecl instanceof GlobalVariable
45
+ or
46
+ //has static or thread local storage duration
47
+ ( outerDecl .isThreadLocal ( ) or outerDecl .isStatic ( ) )
48
+ or
49
+ //is a reference that has been initialized with a constant expression.
50
+ outerDecl .getType ( ) .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
51
+ exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
52
+ or
53
+ //const non-volatile integral or enumeration type and has been initialized with a constant expression
54
+ outerDecl .getType ( ) instanceof NonVolatileConstIntegralOrEnumType and
55
+ exists ( outerDecl .getInitializer ( ) .getExpr ( ) .getValue ( ) )
56
+ or
57
+ //is constexpr and has no mutable members
58
+ outerDecl .isConstexpr ( ) and
59
+ not exists ( Class c |
60
+ c = outerDecl .getType ( ) and not c .getAMember ( ) instanceof MutableVariable
61
+ )
26
62
) and
27
63
innerDecl .getName ( ) = outerDecl .getName ( )
28
64
)
0 commit comments