Variable resolution

This commit is contained in:
Tom Hvitved
2021-05-27 20:59:10 +02:00
parent 28f2527f86
commit f99dc7b266
3 changed files with 53 additions and 0 deletions

View File

@@ -0,0 +1 @@
import codeql_ql.ast.internal.Variable::VarConsistency

View File

@@ -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;

View 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
}
}