mirror of
https://github.com/github/codeql.git
synced 2026-02-07 10:41:06 +01:00
Variable resolution
This commit is contained in:
1
ql/consistency-queries/VariableResolution.ql
Normal file
1
ql/consistency-queries/VariableResolution.ql
Normal file
@@ -0,0 +1 @@
|
||||
import codeql_ql.ast.internal.Variable::VarConsistency
|
||||
@@ -3,6 +3,7 @@ private import codeql_ql.ast.internal.AstNodes
|
||||
private import codeql_ql.ast.internal.Module
|
||||
private import codeql_ql.ast.internal.Predicate
|
||||
private import codeql_ql.ast.internal.Type
|
||||
private import codeql_ql.ast.internal.Variable
|
||||
|
||||
bindingset[name, i]
|
||||
private string indexedMember(string name, int i) { result = name + "(" + i.toString() + ")" }
|
||||
@@ -1172,6 +1173,16 @@ class Identifier extends TIdentifier, Expr {
|
||||
override string getAPrimaryQlClass() { result = "Identifier" }
|
||||
}
|
||||
|
||||
/** An access to a variable. */
|
||||
class VarAccess extends Identifier {
|
||||
private VarDecl decl;
|
||||
|
||||
VarAccess() { resolveVariable(this, decl) }
|
||||
|
||||
/** Gets the accessed variable. */
|
||||
VarDecl getDeclaration() { result = decl }
|
||||
}
|
||||
|
||||
/** A `not` formula. */
|
||||
class Negation extends TNegation, Formula {
|
||||
Generated::Negation neg;
|
||||
|
||||
41
ql/src/codeql_ql/ast/internal/Variable.qll
Normal file
41
ql/src/codeql_ql/ast/internal/Variable.qll
Normal file
@@ -0,0 +1,41 @@
|
||||
import ql
|
||||
import codeql_ql.ast.internal.AstNodes
|
||||
|
||||
private class TScope =
|
||||
TClass or TAggregate or TQuantifier or TSelect or TPredicate or TNewTypeBranch;
|
||||
|
||||
/** A variable scope. */
|
||||
class VariableScope extends TScope, AstNode {
|
||||
/** Gets the outer scope, if any. */
|
||||
VariableScope getOuterScope() { result = scopeOf(this) }
|
||||
|
||||
/** Gets a variable declared directly in this scope. */
|
||||
VarDecl getADeclaration() { result.getParent() = this }
|
||||
|
||||
/** Holds if this scope contains declaration `decl`, either directly or inherited. */
|
||||
predicate contains(VarDecl decl) {
|
||||
decl = this.getADeclaration()
|
||||
or
|
||||
this.getOuterScope().contains(decl) and
|
||||
not this.getADeclaration().getName() = decl.getName()
|
||||
}
|
||||
}
|
||||
|
||||
private AstNode parent(AstNode child) {
|
||||
result = child.getParent() and
|
||||
not child instanceof VariableScope
|
||||
}
|
||||
|
||||
VariableScope scopeOf(AstNode n) { result = parent*(n.getParent()) }
|
||||
|
||||
predicate resolveVariable(Identifier i, VarDecl decl) {
|
||||
scopeOf(i).contains(decl) and
|
||||
decl.getName() = i.getName()
|
||||
}
|
||||
|
||||
module VarConsistency {
|
||||
query predicate multipleVarDecls(VarAccess v, VarDecl decl) {
|
||||
decl = v.getDeclaration() and
|
||||
strictcount(v.getDeclaration()) > 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user