@@ -6,11 +6,22 @@ import cpp
66import codingstandards.cpp.Customizations
77import codingstandards.cpp.Exclusions
88import codingstandards.cpp.Scope
9+ import codingstandards.cpp.ConstHelpers
910
1011abstract class IdentifierHiddenSharedQuery extends Query { }
1112
1213Query getQuery ( ) { result instanceof IdentifierHiddenSharedQuery }
1314
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+
1425/**
1526 * Holds if declaration `innerDecl`, declared in a lambda, hides a declaration `outerDecl` captured by the lambda.
1627 */
@@ -19,10 +30,35 @@ predicate hiddenInLambda(UserVariable outerDecl, UserVariable innerDecl) {
1930 //innerDecl declared inside of the lambda
2031 s .getADeclaration ( ) = innerDecl and
2132 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+ )
2662 ) and
2763 innerDecl .getName ( ) = outerDecl .getName ( )
2864 )
0 commit comments