Skip to content

Commit 43ec1a7

Browse files
committed
QL: Variable resolution
1 parent bf98e96 commit 43ec1a7

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import codeql_ql.ast.internal.Variable::VarConsistency

ql/src/codeql_ql/ast/Ast.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import codeql_ql.ast.internal.AstNodes
33
private import codeql_ql.ast.internal.Module
44
private import codeql_ql.ast.internal.Predicate
55
private import codeql_ql.ast.internal.Type
6+
private import codeql_ql.ast.internal.Variable
67

78
bindingset[name, i]
89
private string indexedMember(string name, int i) { result = name + "(" + i.toString() + ")" }
@@ -1172,6 +1173,16 @@ class Identifier extends TIdentifier, Expr {
11721173
override string getAPrimaryQlClass() { result = "Identifier" }
11731174
}
11741175

1176+
/** An access to a variable. */
1177+
class VarAccess extends Identifier {
1178+
private VarDecl decl;
1179+
1180+
VarAccess() { resolveVariable(this, decl) }
1181+
1182+
/** Gets the accessed variable. */
1183+
VarDecl getDeclaration() { result = decl }
1184+
}
1185+
11751186
/** A `not` formula. */
11761187
class Negation extends TNegation, Formula {
11771188
Generated::Negation neg;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import ql
2+
import codeql_ql.ast.internal.AstNodes
3+
4+
private class TScope =
5+
TClass or TAggregate or TQuantifier or TSelect or TPredicate or TNewTypeBranch;
6+
7+
/** A variable scope. */
8+
class VariableScope extends TScope, AstNode {
9+
/** Gets the outer scope, if any. */
10+
VariableScope getOuterScope() { result = scopeOf(this) }
11+
12+
/** Gets a variable declared directly in this scope. */
13+
VarDecl getADeclaration() { result.getParent() = this }
14+
15+
/** Holds if this scope contains declaration `decl`, either directly or inherited. */
16+
predicate contains(VarDecl decl) {
17+
decl = this.getADeclaration()
18+
or
19+
this.getOuterScope().contains(decl) and
20+
not this.getADeclaration().getName() = decl.getName()
21+
}
22+
}
23+
24+
private AstNode parent(AstNode child) {
25+
result = child.getParent() and
26+
not child instanceof VariableScope
27+
}
28+
29+
VariableScope scopeOf(AstNode n) { result = parent*(n.getParent()) }
30+
31+
predicate resolveVariable(Identifier i, VarDecl decl) {
32+
scopeOf(i).contains(decl) and
33+
decl.getName() = i.getName()
34+
}
35+
36+
module VarConsistency {
37+
query predicate multipleVarDecls(VarAccess v, VarDecl decl) {
38+
decl = v.getDeclaration() and
39+
strictcount(v.getDeclaration()) > 1
40+
}
41+
}

0 commit comments

Comments
 (0)