Cache some predicates

This commit is contained in:
Tom Hvitved
2021-05-28 15:20:55 +02:00
parent 42df07c23a
commit 05d1788c1f
4 changed files with 111 additions and 75 deletions

View File

@@ -2,11 +2,6 @@ import ql
private import codeql_ql.ast.internal.AstNodes as AstNodes
private import codeql_ql.ast.internal.TreeSitter
private newtype TContainerOrModule =
TFile(File f) or
TFolder(Folder f) or
TModule(Module m)
private class ContainerOrModule extends TContainerOrModule {
string getName() { none() }
@@ -146,25 +141,42 @@ private predicate resolveSelectionName(Import imp, ContainerOrModule m, int i) {
)
}
/** Holds if import statement `imp` resolves to `m`. */
predicate resolve(Import imp, FileOrModule m) {
exists(int last |
resolveSelectionName(imp, m, last) and
last = count(int j | exists(imp.getSelectionName(j))) - 1
)
cached
private module Cached {
cached
module NewType {
cached
newtype TContainerOrModule =
TFile(File f) or
TFolder(Folder f) or
TModule(Module m)
}
/** Holds if import statement `imp` resolves to `m`. */
cached
predicate resolve(Import imp, FileOrModule m) {
exists(int last |
resolveSelectionName(imp, m, last) and
last = count(int j | exists(imp.getSelectionName(j))) - 1
)
}
/** Holds if module expression `me` resolves to `m`. */
cached
predicate resolveModuleExpr(ModuleExpr me, FileOrModule m) {
not m = TFile(any(File f | f.getExtension() = "ql")) and
not exists(me.getQualifier()) and
definesModule(getEnclosingModule(me).getEnclosing*(), me.getName(), m, _)
or
exists(FileOrModule mid |
resolveModuleExpr(me.getQualifier(), mid) and
definesModule(mid, me.getName(), m, true)
)
}
}
/** Holds if module expression `me` resolves to `m`. */
predicate resolveModuleExpr(ModuleExpr me, FileOrModule m) {
not m = TFile(any(File f | f.getExtension() = "ql")) and
not exists(me.getQualifier()) and
definesModule(getEnclosingModule(me).getEnclosing*(), me.getName(), m, _)
or
exists(FileOrModule mid |
resolveModuleExpr(me.getQualifier(), mid) and
definesModule(mid, me.getName(), m, true)
)
}
import Cached
private import NewType
boolean getPublicBool(AstNode n) {
if n.(ModuleMember).isPrivate() or n.(NewTypeBranch).getNewType().isPrivate()

View File

@@ -38,59 +38,74 @@ private predicate definesPredicate(
)
}
predicate resolvePredicateExpr(PredicateExpr pe, ClasslessPredicate p) {
exists(FileOrModule m, boolean public |
not exists(pe.getQualifier()) and
m = getEnclosingModule(pe).getEnclosing*() and
public = [false, true]
or
m = pe.getQualifier().getResolvedModule() and
public = true
|
definesPredicate(m, pe.getName(), count(p.getParameter(_)), p, public)
)
}
private predicate resolvePredicateCall(PredicateCall pc, PredicateOrBuiltin p) {
exists(Class c, ClassType t |
c = pc.getParent*() and
t = c.getType() and
p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments())
)
or
exists(FileOrModule m, boolean public |
not exists(pc.getQualifier()) and
m = getEnclosingModule(pc).getEnclosing*() and
public = [false, true]
or
m = pc.getQualifier().getResolvedModule() and
public = true
|
definesPredicate(m, pc.getPredicateName(), pc.getNumberOfArguments(), p.getDeclaration(), public)
)
}
private predicate resolveMemberCall(MemberCall mc, PredicateOrBuiltin p) {
exists(Type t |
t = mc.getBase().getType() and
p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments())
)
}
predicate resolveCall(Call c, PredicateOrBuiltin p) {
resolvePredicateCall(c, p)
or
resolveMemberCall(c, p)
}
private newtype TPredOrBuiltin =
TPred(Predicate p) or
TNewTypeBranch(NewTypeBranch b) or
TBuiltinClassless(string ret, string name, string args) { isBuiltinClassless(ret, name, args) } or
TBuiltinMember(string qual, string ret, string name, string args) {
isBuiltinMember(qual, ret, name, args)
cached
private module Cached {
cached
predicate resolvePredicateExpr(PredicateExpr pe, ClasslessPredicate p) {
exists(FileOrModule m, boolean public |
not exists(pe.getQualifier()) and
m = getEnclosingModule(pe).getEnclosing*() and
public = [false, true]
or
m = pe.getQualifier().getResolvedModule() and
public = true
|
definesPredicate(m, pe.getName(), count(p.getParameter(_)), p, public)
)
}
private predicate resolvePredicateCall(PredicateCall pc, PredicateOrBuiltin p) {
exists(Class c, ClassType t |
c = pc.getParent*() and
t = c.getType() and
p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments())
)
or
exists(FileOrModule m, boolean public |
not exists(pc.getQualifier()) and
m = getEnclosingModule(pc).getEnclosing*() and
public = [false, true]
or
m = pc.getQualifier().getResolvedModule() and
public = true
|
definesPredicate(m, pc.getPredicateName(), pc.getNumberOfArguments(), p.getDeclaration(),
public)
)
}
private predicate resolveMemberCall(MemberCall mc, PredicateOrBuiltin p) {
exists(Type t |
t = mc.getBase().getType() and
p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments())
)
}
cached
predicate resolveCall(Call c, PredicateOrBuiltin p) {
resolvePredicateCall(c, p)
or
resolveMemberCall(c, p)
}
cached
module NewTypeDef {
cached
newtype TPredOrBuiltin =
TPred(Predicate p) or
TNewTypeBranch(NewTypeBranch b) or
TBuiltinClassless(string ret, string name, string args) {
isBuiltinClassless(ret, name, args)
} or
TBuiltinMember(string qual, string ret, string name, string args) {
isBuiltinMember(qual, ret, name, args)
}
}
}
import Cached
private import NewTypeDef
class PredicateOrBuiltin extends TPredOrBuiltin {
string getName() { none() }

View File

@@ -4,6 +4,7 @@ private import codeql_ql.ast.internal.TreeSitter
private import codeql_ql.ast.internal.Module
private import codeql_ql.ast.internal.Predicate
cached
private newtype TType =
TClass(Class c) { isActualClass(c) } or
TNewType(NewType n) or
@@ -257,6 +258,7 @@ class DatabaseType extends Type, TDatabase {
override string getName() { result = name }
}
cached
predicate resolveTypeExpr(TypeExpr te, Type t) {
if te.isDBType()
then t = TDatabase(te.getClassName())

View File

@@ -65,9 +65,16 @@ private string getName(Identifier i) {
)
}
predicate resolveVariable(Identifier i, VarDef decl) { scopeOf(i).containsVar(decl, getName(i)) }
cached
private module Cached {
cached
predicate resolveVariable(Identifier i, VarDef decl) { scopeOf(i).containsVar(decl, getName(i)) }
predicate resolveField(Identifier i, VarDef decl) { scopeOf(i).containsField(decl, getName(i)) }
cached
predicate resolveField(Identifier i, VarDef decl) { scopeOf(i).containsField(decl, getName(i)) }
}
import Cached
module VarConsistency {
query predicate multipleVarDefs(VarAccess v, VarDef decl) {