mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge pull request #129 from github/erik-krogh/cartesian
various new improvements and queries
This commit is contained in:
@@ -49,6 +49,7 @@ class AstNode extends TAstNode {
|
||||
/**
|
||||
* Gets the parent in the AST for this node.
|
||||
*/
|
||||
cached
|
||||
AstNode getParent() { result.getAChild(_) = this }
|
||||
|
||||
/**
|
||||
@@ -74,12 +75,14 @@ class AstNode extends TAstNode {
|
||||
predicate hasAnnotation(string name) { this.getAnAnnotation().getName() = name }
|
||||
|
||||
/** Gets an annotation of this AST node. */
|
||||
Annotation getAnAnnotation() { toQL(this).getParent() = toQL(result).getParent() }
|
||||
Annotation getAnAnnotation() {
|
||||
toQL(this).getParent() = pragma[only_bind_out](toQL(result)).getParent()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the predicate that contains this AST node.
|
||||
*/
|
||||
pragma[noinline]
|
||||
cached
|
||||
Predicate getEnclosingPredicate() { this = getANodeInPredicate(result) }
|
||||
}
|
||||
|
||||
@@ -563,8 +566,10 @@ class VarDecl extends TVarDecl, VarDef, Declaration {
|
||||
)
|
||||
}
|
||||
|
||||
/** If this is a field, returns the class type that declares it. */
|
||||
ClassType getDeclaringType() { result.getDeclaration().getAField() = this }
|
||||
/** If this is declared in a field, returns the class type that declares it. */
|
||||
ClassType getDeclaringType() {
|
||||
exists(FieldDecl f | f.getVarDecl() = this and result = f.getParent().(Class).getType())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a class field that overrides the field `other`.
|
||||
@@ -580,6 +585,32 @@ class VarDecl extends TVarDecl, VarDef, Declaration {
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A field declaration;
|
||||
*/
|
||||
class FieldDecl extends TFieldDecl, AstNode {
|
||||
QL::Field f;
|
||||
|
||||
FieldDecl() { this = TFieldDecl(f) }
|
||||
|
||||
VarDecl getVarDecl() { toQL(result) = f.getChild() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = directMember("getVarDecl") and result = this.getVarDecl()
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FieldDecl" }
|
||||
|
||||
/** Holds if this field is annotated as overriding another field. */
|
||||
predicate isOverride() { this.hasAnnotation("override") }
|
||||
|
||||
string getName() { result = getVarDecl().getName() }
|
||||
|
||||
override QLDoc getQLDoc() { result = any(Class c).getQLDocFor(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type reference, such as `DataFlow::Node`.
|
||||
*/
|
||||
@@ -716,10 +747,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
|
||||
*/
|
||||
CharPred getCharPred() { toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_) }
|
||||
|
||||
AstNode getMember(int i) {
|
||||
toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_) or
|
||||
toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_).(QL::Field).getChild()
|
||||
}
|
||||
AstNode getMember(int i) { toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_) }
|
||||
|
||||
QLDoc getQLDocFor(AstNode m) {
|
||||
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
|
||||
@@ -743,9 +771,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
|
||||
/**
|
||||
* Gets a field in this class.
|
||||
*/
|
||||
VarDecl getAField() {
|
||||
toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_).(QL::Field).getChild()
|
||||
}
|
||||
FieldDecl getAField() { result = getMember(_) }
|
||||
|
||||
/**
|
||||
* Gets a super-type referenced in the `extends` part of the class declaration.
|
||||
@@ -1102,9 +1128,15 @@ class Conjunction extends TConjunction, AstNode, Formula {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Conjunction" }
|
||||
|
||||
/** Gets an operand to this formula. */
|
||||
/** Gets an operand to this conjunction. */
|
||||
Formula getAnOperand() { toQL(result) in [conj.getLeft(), conj.getRight()] }
|
||||
|
||||
/** Gets the left operand to this conjunction. */
|
||||
Formula getLeft() { toQL(result) = conj.getLeft() }
|
||||
|
||||
/** Gets the right operand to this conjunction. */
|
||||
Formula getRight() { toQL(result) = conj.getRight() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
@@ -1120,9 +1152,15 @@ class Disjunction extends TDisjunction, AstNode, Formula {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Disjunction" }
|
||||
|
||||
/** Gets an operand to this formula. */
|
||||
/** Gets an operand to this disjunction. */
|
||||
Formula getAnOperand() { toQL(result) in [disj.getLeft(), disj.getRight()] }
|
||||
|
||||
/** Gets the left operand to this disjunction */
|
||||
Formula getLeft() { toQL(result) = disj.getLeft() }
|
||||
|
||||
/** Gets the right operand to this disjunction */
|
||||
Formula getRight() { toQL(result) = disj.getRight() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
@@ -1130,23 +1168,6 @@ class Disjunction extends TDisjunction, AstNode, Formula {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison operator, such as `<` or `=`.
|
||||
*/
|
||||
class ComparisonOp extends TComparisonOp, AstNode {
|
||||
QL::Compop op;
|
||||
|
||||
ComparisonOp() { this = TComparisonOp(op) }
|
||||
|
||||
/**
|
||||
* Gets a string representing the operator.
|
||||
* E.g. "<" or "=".
|
||||
*/
|
||||
ComparisonSymbol getSymbol() { result = op.getValue() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ComparisonOp" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A literal expression, such as `6` or `true` or `"foo"`.
|
||||
*/
|
||||
@@ -1243,10 +1264,7 @@ class ComparisonFormula extends TComparisonFormula, Formula {
|
||||
Expr getAnOperand() { result in [this.getLeftOperand(), this.getRightOperand()] }
|
||||
|
||||
/** Gets the operator of this comparison. */
|
||||
ComparisonOp getOperator() { toQL(result) = comp.getChild() }
|
||||
|
||||
/** Gets the symbol of this comparison (as a string). */
|
||||
ComparisonSymbol getSymbol() { result = this.getOperator().getSymbol() }
|
||||
ComparisonSymbol getOperator() { result = comp.getChild().getValue() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ComparisonFormula" }
|
||||
|
||||
@@ -1256,8 +1274,6 @@ class ComparisonFormula extends TComparisonFormula, Formula {
|
||||
pred = directMember("getLeftOperand") and result = this.getLeftOperand()
|
||||
or
|
||||
pred = directMember("getRightOperand") and result = this.getRightOperand()
|
||||
or
|
||||
pred = directMember("getOperator") and result = this.getOperator()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2218,6 +2234,8 @@ class Annotation extends TAnnotation, AstNode {
|
||||
/** Gets the node corresponding to the field `name`. */
|
||||
string getName() { result = annot.getName().getValue() }
|
||||
|
||||
override AstNode getParent() { result = AstNode.super.getParent() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
|
||||
@@ -8,6 +8,7 @@ newtype TAstNode =
|
||||
TQLDoc(QL::Qldoc qldoc) or
|
||||
TClasslessPredicate(QL::ClasslessPredicate pred) or
|
||||
TVarDecl(QL::VarDecl decl) or
|
||||
TFieldDecl(QL::Field field) or
|
||||
TClass(QL::Dataclass dc) or
|
||||
TCharPred(QL::Charpred pred) or
|
||||
TClassPredicate(QL::MemberPredicate pred) or
|
||||
@@ -21,7 +22,6 @@ newtype TAstNode =
|
||||
TDisjunction(QL::Disjunction disj) or
|
||||
TConjunction(QL::Conjunction conj) or
|
||||
TComparisonFormula(QL::CompTerm comp) or
|
||||
TComparisonOp(QL::Compop op) or
|
||||
TQuantifier(QL::Quantified quant) or
|
||||
TFullAggregate(QL::Aggregate agg) { agg.getChild(_) instanceof QL::FullAggregateBody } or
|
||||
TExprAggregate(QL::Aggregate agg) { agg.getChild(_) instanceof QL::ExprAggregateBody } or
|
||||
@@ -90,7 +90,6 @@ private QL::AstNode toQLFormula(AST::AstNode n) {
|
||||
n = TConjunction(result) or
|
||||
n = TDisjunction(result) or
|
||||
n = TComparisonFormula(result) or
|
||||
n = TComparisonOp(result) or
|
||||
n = TQuantifier(result) or
|
||||
n = TFullAggregate(result) or
|
||||
n = TIdentifier(result) or
|
||||
@@ -127,6 +126,7 @@ private QL::AstNode toGenerateYAML(AST::AstNode n) {
|
||||
/**
|
||||
* Gets the underlying TreeSitter entity for a given AST node.
|
||||
*/
|
||||
cached
|
||||
QL::AstNode toQL(AST::AstNode n) {
|
||||
result = toQLExpr(n)
|
||||
or
|
||||
@@ -150,6 +150,8 @@ QL::AstNode toQL(AST::AstNode n) {
|
||||
or
|
||||
n = TVarDecl(result)
|
||||
or
|
||||
n = TFieldDecl(result)
|
||||
or
|
||||
n = TClass(result)
|
||||
or
|
||||
n = TCharPred(result)
|
||||
|
||||
@@ -134,7 +134,7 @@ predicate predOverrides(ClassPredicate sub, ClassPredicate sup) {
|
||||
}
|
||||
|
||||
private VarDecl declaredField(ClassType ty, string name) {
|
||||
result = ty.getDeclaration().getAField() and
|
||||
result = ty.getDeclaration().getAField().getVarDecl() and
|
||||
result.getName() = name
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class VariableScope extends TScope, AstNode {
|
||||
predicate containsField(VarDef decl, string name) {
|
||||
name = decl.getName() and
|
||||
(
|
||||
decl = this.(Class).getAField()
|
||||
decl = this.(Class).getAField().getVarDecl()
|
||||
or
|
||||
this.getOuterScope().containsField(decl, name) and
|
||||
not exists(this.getADefinition(name))
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
/**
|
||||
* @name Prefix or suffix predicate calls when comparing with literal
|
||||
* @description Using 'myString.prefix(n) = "..."' instead of 'myString.matches("...%")'
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @id ql/prefix-or-suffix-equality-check
|
||||
* @tags performance
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import ql
|
||||
import codeql_ql.ast.internal.Predicate
|
||||
import codeql_ql.ast.internal.Builtins
|
||||
@@ -29,7 +19,7 @@ class SuffixPredicateCall extends Call {
|
||||
}
|
||||
|
||||
class EqFormula extends ComparisonFormula {
|
||||
EqFormula() { this.getSymbol() = "=" }
|
||||
EqFormula() { this.getOperator() = "=" }
|
||||
}
|
||||
|
||||
bindingset[s]
|
||||
@@ -48,6 +38,17 @@ class FixPredicateCall extends Call {
|
||||
FixPredicateCall() { this instanceof PrefixPredicateCall or this instanceof SuffixPredicateCall }
|
||||
}
|
||||
|
||||
from EqFormula eq, FixPredicateCall call, String literal
|
||||
where eq.getAnOperand() = call and eq.getAnOperand() = literal
|
||||
select eq, "Use " + getMessage(call, literal) + " instead."
|
||||
class RegexpMatchPredicate extends BuiltinPredicate {
|
||||
RegexpMatchPredicate() { this = any(StringClass sc).getClassPredicate("regexpMatch", 1) }
|
||||
}
|
||||
|
||||
predicate canUseMatchInsteadOfRegexpMatch(Call c, string matchesStr) {
|
||||
c.getTarget() instanceof RegexpMatchPredicate and
|
||||
exists(string raw | raw = c.getArgument(0).(String).getValue() |
|
||||
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)$", _)
|
||||
or
|
||||
matchesStr = raw.regexpCapture("^(\\w+)\\.\\*$", _) + "%"
|
||||
or
|
||||
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)\\.\\*$", _) + "%"
|
||||
)
|
||||
}
|
||||
20
ql/src/codeql_ql/style/ImplicitThisQuery.qll
Normal file
20
ql/src/codeql_ql/style/ImplicitThisQuery.qll
Normal file
@@ -0,0 +1,20 @@
|
||||
import ql
|
||||
|
||||
MemberCall explicitThisCallInFile(File f) {
|
||||
result.getLocation().getFile() = f and
|
||||
result.getBase() instanceof ThisAccess and
|
||||
// Exclude `this.(Type).whatever(...)`, as some files have that as their only instance of `this`.
|
||||
not result = any(InlineCast c).getBase()
|
||||
}
|
||||
|
||||
PredicateCall implicitThisCallInFile(File f) {
|
||||
result.getLocation().getFile() = f and
|
||||
exists(result.getTarget().getDeclaringType().getASuperType()) and
|
||||
// Exclude `SomeModule::whatever(...)`
|
||||
not exists(result.getQualifier())
|
||||
}
|
||||
|
||||
PredicateCall confusingImplicitThisCall(File f) {
|
||||
result = implicitThisCallInFile(f) and
|
||||
exists(explicitThisCallInFile(f))
|
||||
}
|
||||
35
ql/src/codeql_ql/style/RedundantInlineCastQuery.qll
Normal file
35
ql/src/codeql_ql/style/RedundantInlineCastQuery.qll
Normal file
@@ -0,0 +1,35 @@
|
||||
import ql
|
||||
|
||||
class RedundantInlineCast extends AstNode instanceof InlineCast {
|
||||
Type t;
|
||||
|
||||
RedundantInlineCast() {
|
||||
t = unique( | | super.getType()) and
|
||||
(
|
||||
// The cast is to the type the base expression already has
|
||||
t = unique( | | super.getBase().getType())
|
||||
or
|
||||
// The cast is to the same type as the other expression in an equality comparison
|
||||
exists(ComparisonFormula comp, Expr other | comp.getOperator() = "=" |
|
||||
this = comp.getAnOperand() and
|
||||
other = comp.getAnOperand() and
|
||||
this != other and
|
||||
t = unique( | | other.getType()) and
|
||||
not other instanceof InlineCast // we don't want to risk both sides being "redundant"
|
||||
)
|
||||
or
|
||||
exists(Call call, int i, Predicate target |
|
||||
this = call.getArgument(i) and
|
||||
target = unique( | | call.getTarget()) and
|
||||
t = unique( | | target.getParameterType(i))
|
||||
)
|
||||
) and
|
||||
// noopt can require explicit casts
|
||||
not exists(Annotation annon | annon = this.getEnclosingPredicate().getAnAnnotation() |
|
||||
annon.getName() = "pragma" and
|
||||
annon.getArgs(0).getValue() = "noopt"
|
||||
)
|
||||
}
|
||||
|
||||
TypeExpr getTypeExpr() { result = super.getTypeExpr() }
|
||||
}
|
||||
70
ql/src/codeql_ql/style/UseInstanceofExtensionQuery.qll
Normal file
70
ql/src/codeql_ql/style/UseInstanceofExtensionQuery.qll
Normal file
@@ -0,0 +1,70 @@
|
||||
import ql
|
||||
|
||||
/**
|
||||
* Gets a class where the charpred has an `this instanceof type` expression.
|
||||
*/
|
||||
predicate instanceofThisInCharPred(Class c, Type type) {
|
||||
exists(InstanceOf instanceOf |
|
||||
instanceOf = c.getCharPred().getBody()
|
||||
or
|
||||
exists(Conjunction conj |
|
||||
conj = c.getCharPred().getBody() and
|
||||
instanceOf = conj.getAnOperand()
|
||||
)
|
||||
|
|
||||
instanceOf.getExpr() instanceof ThisAccess and
|
||||
type = instanceOf.getType().getResolvedType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `c` uses the casting based range pattern, which could be replaced with `instanceof type`.
|
||||
*/
|
||||
predicate usesCastingBasedInstanceof(Class c, Type type) {
|
||||
instanceofThisInCharPred(c, type) and
|
||||
// require that there is a call to the range class that matches the name of the enclosing predicate
|
||||
exists(InlineCast cast, MemberCall call |
|
||||
cast = getAThisCast(c, type) and
|
||||
call.getBase() = cast and
|
||||
cast.getEnclosingPredicate().getName() = call.getMemberName()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets an inline cast that cases `this` to `type` inside a class predicate for `c`. */
|
||||
InlineCast getAThisCast(Class c, Type type) {
|
||||
exists(MemberCall call |
|
||||
call.getEnclosingPredicate() = c.getAClassPredicate() and
|
||||
result = call.getBase() and
|
||||
result.getBase() instanceof ThisAccess and
|
||||
result.getTypeExpr().getResolvedType() = type
|
||||
)
|
||||
}
|
||||
|
||||
predicate usesFieldBasedInstanceof(Class c, TypeExpr type, VarDecl field, ComparisonFormula comp) {
|
||||
exists(FieldAccess fieldAccess |
|
||||
c.getCharPred().getBody() = comp or
|
||||
c.getCharPred().getBody().(Conjunction).getAnOperand() = comp
|
||||
|
|
||||
comp.getOperator() = "=" and
|
||||
comp.getEnclosingPredicate() = c.getCharPred() and
|
||||
comp.getAnOperand() instanceof ThisAccess and
|
||||
comp.getAnOperand() = fieldAccess and
|
||||
fieldAccess.getDeclaration() = field and
|
||||
field.getTypeExpr() = type
|
||||
) and
|
||||
// require that there is a call to the range field that matches the name of the enclosing predicate
|
||||
exists(FieldAccess access, MemberCall call |
|
||||
access = getARangeFieldAccess(c, field, _) and
|
||||
call.getBase() = access and
|
||||
access.getEnclosingPredicate().getName() = call.getMemberName()
|
||||
)
|
||||
}
|
||||
|
||||
FieldAccess getARangeFieldAccess(Class c, VarDecl field, string name) {
|
||||
exists(MemberCall call |
|
||||
result = call.getBase() and
|
||||
result.getDeclaration() = field and
|
||||
name = call.getMemberName() and
|
||||
call.getEnclosingPredicate().(ClassPredicate).getParent() = c
|
||||
)
|
||||
}
|
||||
124
ql/src/codeql_ql/style/UseSetLiteralQuery.qll
Normal file
124
ql/src/codeql_ql/style/UseSetLiteralQuery.qll
Normal file
@@ -0,0 +1,124 @@
|
||||
import ql
|
||||
|
||||
/**
|
||||
* A chain of disjunctions treated as one object. For example the following is
|
||||
* a chain of disjunctions with three operands:
|
||||
* ```
|
||||
* a or b or c
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionChain extends Disjunction {
|
||||
DisjunctionChain() { not exists(Disjunction parent | parent.getAnOperand() = this) }
|
||||
|
||||
/**
|
||||
* Gets any operand of the chain.
|
||||
*/
|
||||
Formula getOperand(int i) {
|
||||
result =
|
||||
rank[i + 1](Formula operand, Location l |
|
||||
operand = getAnOperand*() and
|
||||
not operand instanceof Disjunction and
|
||||
l = operand.getLocation()
|
||||
|
|
||||
operand order by l.getStartLine(), l.getStartColumn()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An equality comparison with a `Literal`. For example:
|
||||
* ```
|
||||
* x = 4
|
||||
* ```
|
||||
*/
|
||||
class EqualsLiteral extends ComparisonFormula {
|
||||
EqualsLiteral() {
|
||||
getOperator() = "=" and
|
||||
getAnOperand() instanceof Literal
|
||||
}
|
||||
|
||||
AstNode getOther() {
|
||||
result = getAnOperand() and
|
||||
not result instanceof Literal
|
||||
}
|
||||
|
||||
Literal getLiteral() { result = getAnOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A chain of disjunctions where each operand is an equality comparison between
|
||||
* the same thing and various `Literal`s. For example:
|
||||
* ```
|
||||
* x = 4 or
|
||||
* x = 5 or
|
||||
* x = 6
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionEqualsLiteral extends DisjunctionChain {
|
||||
AstNode firstOperand;
|
||||
|
||||
DisjunctionEqualsLiteral() {
|
||||
// VarAccess on the same variable
|
||||
exists(VarDef v |
|
||||
forex(Formula f | f = getOperand(_) |
|
||||
f.(EqualsLiteral).getAnOperand().(VarAccess).getDeclaration() = v
|
||||
) and
|
||||
firstOperand = getOperand(0).(EqualsLiteral).getAnOperand() and
|
||||
firstOperand.(VarAccess).getDeclaration() = v
|
||||
)
|
||||
or
|
||||
// FieldAccess on the same variable
|
||||
exists(VarDecl v |
|
||||
forex(Formula f | f = getOperand(_) |
|
||||
f.(EqualsLiteral).getAnOperand().(FieldAccess).getDeclaration() = v
|
||||
) and
|
||||
firstOperand = getOperand(0).(EqualsLiteral).getAnOperand() and
|
||||
firstOperand.(FieldAccess).getDeclaration() = v
|
||||
)
|
||||
or
|
||||
// ThisAccess
|
||||
forex(Formula f | f = getOperand(_) | f.(EqualsLiteral).getAnOperand() instanceof ThisAccess) and
|
||||
firstOperand = getOperand(0).(EqualsLiteral).getAnOperand().(ThisAccess)
|
||||
or
|
||||
// ResultAccess
|
||||
forex(Formula f | f = getOperand(_) | f.(EqualsLiteral).getAnOperand() instanceof ResultAccess) and
|
||||
firstOperand = getOperand(0).(EqualsLiteral).getAnOperand().(ResultAccess)
|
||||
// (in principle something like GlobalValueNumbering could be used to generalize this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first "thing" that is the same thing in this chain of equalities.
|
||||
*/
|
||||
AstNode getFirstOperand() { result = firstOperand }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call with a single `Literal` argument. For example:
|
||||
* ```
|
||||
* myPredicate(4)
|
||||
* ```
|
||||
*/
|
||||
class CallLiteral extends Call {
|
||||
CallLiteral() {
|
||||
getNumberOfArguments() = 1 and
|
||||
getArgument(0) instanceof Literal
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A chain of disjunctions where each operand is a call to the same predicate
|
||||
* using various `Literal`s. For example:
|
||||
* ```
|
||||
* myPredicate(4) or
|
||||
* myPredicate(5) or
|
||||
* myPredicate(6)
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionPredicateLiteral extends DisjunctionChain {
|
||||
DisjunctionPredicateLiteral() {
|
||||
// Call to the same target
|
||||
exists(PredicateOrBuiltin target |
|
||||
forex(Formula f | f = getOperand(_) | f.(CallLiteral).getTarget() = target)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ predicate usesThis(ClassPredicate pred) {
|
||||
|
||||
predicate isLiteralComparison(ComparisonFormula eq) {
|
||||
exists(Expr lhs, Expr rhs |
|
||||
eq.getSymbol() = "=" and
|
||||
eq.getOperator() = "=" and
|
||||
eq.getAnOperand() = lhs and
|
||||
eq.getAnOperand() = rhs and
|
||||
(
|
||||
|
||||
26
ql/src/queries/performance/InefficientStringComparison.ql
Normal file
26
ql/src/queries/performance/InefficientStringComparison.ql
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @name Inefficient string comparison
|
||||
* @description The `.matches` predicate is usually the best performing way to compare strings.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @id ql/inefficient-string-comparison
|
||||
* @tags performance
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import ql
|
||||
import codeql_ql.performance.InefficientStringComparisonQuery
|
||||
|
||||
from AstNode node, string msg
|
||||
where
|
||||
exists(EqFormula eq, FixPredicateCall call, String literal |
|
||||
node = eq and msg = "Use " + getMessage(call, literal) + " instead."
|
||||
|
|
||||
eq.getAnOperand() = call and eq.getAnOperand() = literal
|
||||
)
|
||||
or
|
||||
exists(string matchesStr |
|
||||
canUseMatchInsteadOfRegexpMatch(node, matchesStr) and
|
||||
msg = "Use matches(\"" + matchesStr + "\") instead"
|
||||
)
|
||||
select node, msg
|
||||
@@ -78,7 +78,7 @@ predicate transitivePred(Predicate p, AstNode tc) {
|
||||
or
|
||||
exists(ComparisonFormula eq, Call c |
|
||||
body = eq and
|
||||
eq.getSymbol() = "=" and
|
||||
eq.getOperator() = "=" and
|
||||
transitiveCall(c, tc) and
|
||||
getArg(c, _) instanceof Identifier and
|
||||
eq.getAnOperand() = c and
|
||||
@@ -141,7 +141,7 @@ predicate valueStep(Expr e1, Expr e2) {
|
||||
)
|
||||
or
|
||||
exists(ComparisonFormula eq |
|
||||
eq.getSymbol() = "=" and
|
||||
eq.getOperator() = "=" and
|
||||
eq.getAnOperand() = e1 and
|
||||
eq.getAnOperand() = e2 and
|
||||
e1 != e2
|
||||
|
||||
212
ql/src/queries/performance/VarUnusedInDisjunct.ql
Normal file
212
ql/src/queries/performance/VarUnusedInDisjunct.ql
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @name Var only used in one side of disjunct.
|
||||
* @description Only using a variable on one side of a disjunction can cause a cartesian product.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id ql/var-unused-in-disjunct
|
||||
* @tags maintainability
|
||||
* performance
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import ql
|
||||
|
||||
/**
|
||||
* Holds if `node` bind `var` in a (transitive) child node.
|
||||
* Is a practical approximation that ignores `not` and many other features.
|
||||
*/
|
||||
pragma[noinline]
|
||||
predicate alwaysBindsVar(VarDef var, AstNode node) {
|
||||
// base case
|
||||
node.(VarAccess).getDeclaration() = var and
|
||||
not isSmallType(var.getType()) // <- early pruning
|
||||
or
|
||||
// recursive cases
|
||||
alwaysBindsVar(var, node.getAChild(_)) and // the recursive step, go one step up to the parent.
|
||||
not node.(FullAggregate).getAnArgument() = var and // except if the parent defines the variable, then we stop.
|
||||
not node.(Quantifier).getAnArgument() = var and
|
||||
not node instanceof EffectiveDisjunction // for disjunctions, we need to check both sides.
|
||||
or
|
||||
exists(EffectiveDisjunction disj | disj = node |
|
||||
alwaysBindsVar(var, disj.getLeft()) and
|
||||
alwaysBindsVar(var, disj.getRight())
|
||||
)
|
||||
or
|
||||
exists(EffectiveDisjunction disj | disj = node |
|
||||
alwaysBindsVar(var, disj.getAnOperand()) and
|
||||
disj.getAnOperand() instanceof NoneCall
|
||||
)
|
||||
or
|
||||
exists(IfFormula ifForm | ifForm = node | alwaysBindsVar(var, ifForm.getCondition()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if we assume `t` is a small type, and
|
||||
* variables of this type are therefore not an issue in cartesian products.
|
||||
*/
|
||||
predicate isSmallType(Type t) {
|
||||
t.getName() = "string" // DataFlow::Configuration and the like
|
||||
or
|
||||
exists(NewType newType | newType = t.getDeclaration() |
|
||||
forex(NewTypeBranch branch | branch = newType.getABranch() | branch.getArity() = 0)
|
||||
)
|
||||
or
|
||||
t.getName() = "boolean"
|
||||
or
|
||||
exists(NewType newType | newType = t.getDeclaration() |
|
||||
forex(NewTypeBranch branch | branch = newType.getABranch() |
|
||||
isSmallType(branch.getReturnType())
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(NewTypeBranch branch | t = branch.getReturnType() |
|
||||
forall(Type param | param = branch.getParameterType(_) | isSmallType(param))
|
||||
)
|
||||
or
|
||||
isSmallType(t.getASuperType())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred` is inlined.
|
||||
*/
|
||||
predicate isInlined(Predicate pred) {
|
||||
exists(Annotation inline |
|
||||
inline = pred.getAnAnnotation() and
|
||||
inline.getName() = "pragma" and
|
||||
inline.getArgs(0).getValue() = "inline"
|
||||
)
|
||||
or
|
||||
pred.getAnAnnotation().getName() = "bindingset"
|
||||
}
|
||||
|
||||
/**
|
||||
* An AstNode that acts like a disjunction.
|
||||
*/
|
||||
class EffectiveDisjunction extends AstNode {
|
||||
EffectiveDisjunction() {
|
||||
this instanceof IfFormula
|
||||
or
|
||||
this instanceof Disjunction
|
||||
}
|
||||
|
||||
/** Gets the left operand of this disjunction. */
|
||||
AstNode getLeft() {
|
||||
result = this.(IfFormula).getThenPart()
|
||||
or
|
||||
result = this.(Disjunction).getLeft()
|
||||
}
|
||||
|
||||
/** Gets the right operand of this disjunction. */
|
||||
AstNode getRight() {
|
||||
result = this.(IfFormula).getElsePart()
|
||||
or
|
||||
result = this.(Disjunction).getRight()
|
||||
}
|
||||
|
||||
/** Gets any of the operands of this disjunction. */
|
||||
AstNode getAnOperand() { result = [this.getLeft(), this.getRight()] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `disj` only uses `var` in one of its branches.
|
||||
*/
|
||||
pragma[noinline]
|
||||
predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var) {
|
||||
alwaysBindsVar(var, disj.getLeft()) and
|
||||
not alwaysBindsVar(var, disj.getRight())
|
||||
or
|
||||
not alwaysBindsVar(var, disj.getLeft()) and
|
||||
alwaysBindsVar(var, disj.getRight())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `comp` is an equality comparison that has a low number of results.
|
||||
*/
|
||||
predicate isTinyAssignment(ComparisonFormula comp) {
|
||||
comp.getOperator() = "=" and
|
||||
(
|
||||
isSmallType(comp.getAnOperand().getType())
|
||||
or
|
||||
comp.getAnOperand() instanceof Literal
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An AstNode that acts like a conjunction.
|
||||
*/
|
||||
class EffectiveConjunction extends AstNode {
|
||||
EffectiveConjunction() {
|
||||
this instanceof Conjunction
|
||||
or
|
||||
this instanceof Exists
|
||||
}
|
||||
|
||||
/** Gets the left operand of this conjunction */
|
||||
Formula getLeft() {
|
||||
result = this.(Conjunction).getLeft()
|
||||
or
|
||||
result = this.(Exists).getRange()
|
||||
}
|
||||
|
||||
/** Gets the right operand of this conjunction */
|
||||
Formula getRight() {
|
||||
result = this.(Conjunction).getRight()
|
||||
or
|
||||
result = this.(Exists).getFormula()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a sub-node of a node that always binds `var`.
|
||||
*/
|
||||
predicate varIsAlwaysBound(VarDef var, AstNode node) {
|
||||
// base case
|
||||
alwaysBindsVar(var, node) and
|
||||
onlyUseInOneBranch(_, var) // <- manual magic
|
||||
or
|
||||
// recursive cases
|
||||
exists(AstNode parent | node.getParent() = parent | varIsAlwaysBound(var, parent))
|
||||
or
|
||||
exists(EffectiveConjunction parent |
|
||||
varIsAlwaysBound(var, parent.getLeft()) and
|
||||
node = parent.getRight()
|
||||
or
|
||||
varIsAlwaysBound(var, parent.getRight()) and
|
||||
node = parent.getLeft()
|
||||
)
|
||||
or
|
||||
exists(IfFormula ifForm | varIsAlwaysBound(var, ifForm.getCondition()) |
|
||||
node = [ifForm.getThenPart(), ifForm.getElsePart()]
|
||||
)
|
||||
or
|
||||
exists(Forall for | varIsAlwaysBound(var, for.getRange()) | node = for.getFormula())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `disj` only uses `var` in one of its branches.
|
||||
* And we should report it as being a bad thing.
|
||||
*/
|
||||
predicate badDisjunction(EffectiveDisjunction disj, VarDef var) {
|
||||
onlyUseInOneBranch(disj, var) and
|
||||
// it's fine if it's always bound further up
|
||||
not varIsAlwaysBound(var, disj) and
|
||||
// none() on one side makes everything fine. (this happens, it's a type-system hack)
|
||||
not disj.getAnOperand() instanceof NoneCall and
|
||||
// inlined predicates might bind unused variables in the context they are used in.
|
||||
not (
|
||||
isInlined(disj.getEnclosingPredicate()) and
|
||||
var = disj.getEnclosingPredicate().getParameter(_)
|
||||
) and
|
||||
// recursion prevention never runs, it's a compile-time check, so we remove those results here
|
||||
not disj.getEnclosingPredicate().getParent().(Class).getName().matches("%RecursionPrevention") and // these are by design
|
||||
// not a small type
|
||||
not isSmallType(var.getType()) and
|
||||
// one of the branches is a tiny assignment. These are usually intentional cartesian products (and not too big).
|
||||
not isTinyAssignment(disj.getAnOperand())
|
||||
}
|
||||
|
||||
from EffectiveDisjunction disj, VarDef var
|
||||
where
|
||||
badDisjunction(disj, var) and
|
||||
not badDisjunction(disj.getParent(), var) // avoid duplicate reporting of the same error
|
||||
select disj, "The variable " + var.getName() + " is only used in one side of disjunct."
|
||||
@@ -9,25 +9,7 @@
|
||||
*/
|
||||
|
||||
import ql
|
||||
|
||||
MemberCall explicitThisCallInFile(File f) {
|
||||
result.getLocation().getFile() = f and
|
||||
result.getBase() instanceof ThisAccess and
|
||||
// Exclude `this.(Type).whatever(...)`, as some files have that as their only instance of `this`.
|
||||
not result = any(InlineCast c).getBase()
|
||||
}
|
||||
|
||||
PredicateCall implicitThisCallInFile(File f) {
|
||||
result.getLocation().getFile() = f and
|
||||
exists(result.getTarget().getDeclaringType().getASuperType()) and
|
||||
// Exclude `SomeModule::whatever(...)`
|
||||
not exists(result.getQualifier())
|
||||
}
|
||||
|
||||
PredicateCall confusingImplicitThisCall(File f) {
|
||||
result = implicitThisCallInFile(f) and
|
||||
exists(explicitThisCallInFile(f))
|
||||
}
|
||||
import codeql_ql.style.ImplicitThisQuery
|
||||
|
||||
from PredicateCall c
|
||||
where c = confusingImplicitThisCall(_)
|
||||
|
||||
16
ql/src/queries/style/RedundantInlineCast.ql
Normal file
16
ql/src/queries/style/RedundantInlineCast.ql
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @name Redundant inline cast
|
||||
* @description Redundant inline casts
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @id ql/redundant-inline-cast
|
||||
* @tags maintainability
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import ql
|
||||
import codeql_ql.style.RedundantInlineCastQuery
|
||||
|
||||
from RedundantInlineCast cast
|
||||
select cast, "Redundant cast to $@", cast.getTypeExpr(),
|
||||
cast.getTypeExpr().getResolvedType().getName()
|
||||
@@ -227,7 +227,7 @@ module DataFlow {
|
||||
)
|
||||
or
|
||||
exists(ComparisonFormula eq |
|
||||
eq.getSymbol() = "=" and
|
||||
eq.getOperator() = "=" and
|
||||
eq.getAnOperand() = e1 and
|
||||
eq.getAnOperand() = e2 and
|
||||
e1 != e2
|
||||
|
||||
21
ql/src/queries/style/UseInstanceofExtension.ql
Normal file
21
ql/src/queries/style/UseInstanceofExtension.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Suggest using non-extending subtype relationships.
|
||||
* @description Non-extending subtypes ("instanceof extensions") are generally preferrable to instanceof expressions in characteristic predicates.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id ql/suggest-instanceof-extension
|
||||
* @tags maintainability
|
||||
* @precision medium
|
||||
*/
|
||||
|
||||
import ql
|
||||
import codeql_ql.style.UseInstanceofExtensionQuery
|
||||
|
||||
from Class c, Type type, string message
|
||||
where
|
||||
(
|
||||
usesCastingBasedInstanceof(c, type) or
|
||||
usesFieldBasedInstanceof(c, any(TypeExpr te | te.getResolvedType() = type), _, _)
|
||||
) and
|
||||
message = "consider defining $@ as non-extending subtype of $@"
|
||||
select c, message, c, c.getName(), type, type.getName()
|
||||
@@ -9,107 +9,7 @@
|
||||
*/
|
||||
|
||||
import ql
|
||||
|
||||
/**
|
||||
* A chain of disjunctions treated as one object. For example the following is
|
||||
* a chain of disjunctions with three operands:
|
||||
* ```
|
||||
* a or b or c
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionChain extends Disjunction {
|
||||
DisjunctionChain() { not exists(Disjunction parent | parent.getAnOperand() = this) }
|
||||
|
||||
/**
|
||||
* Gets any operand of the chain.
|
||||
*/
|
||||
Formula getAnOperandRec() {
|
||||
result = getAnOperand*() and
|
||||
not result instanceof Disjunction
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An equality comparison with a `Literal`. For example:
|
||||
* ```
|
||||
* x = 4
|
||||
* ```
|
||||
*/
|
||||
class EqualsLiteral extends ComparisonFormula {
|
||||
EqualsLiteral() {
|
||||
getSymbol() = "=" and
|
||||
getAnOperand() instanceof Literal
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A chain of disjunctions where each operand is an equality comparison between
|
||||
* the same thing and various `Literal`s. For example:
|
||||
* ```
|
||||
* x = 4 or
|
||||
* x = 5 or
|
||||
* x = 6
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionEqualsLiteral extends DisjunctionChain {
|
||||
DisjunctionEqualsLiteral() {
|
||||
// VarAccess on the same variable
|
||||
exists(VarDef v |
|
||||
forex(Formula f | f = getAnOperandRec() |
|
||||
f.(EqualsLiteral).getAnOperand().(VarAccess).getDeclaration() = v
|
||||
)
|
||||
)
|
||||
or
|
||||
// FieldAccess on the same variable
|
||||
exists(VarDecl v |
|
||||
forex(Formula f | f = getAnOperandRec() |
|
||||
f.(EqualsLiteral).getAnOperand().(FieldAccess).getDeclaration() = v
|
||||
)
|
||||
)
|
||||
or
|
||||
// ThisAccess
|
||||
forex(Formula f | f = getAnOperandRec() |
|
||||
f.(EqualsLiteral).getAnOperand() instanceof ThisAccess
|
||||
)
|
||||
or
|
||||
// ResultAccess
|
||||
forex(Formula f | f = getAnOperandRec() |
|
||||
f.(EqualsLiteral).getAnOperand() instanceof ResultAccess
|
||||
)
|
||||
// (in principle something like GlobalValueNumbering could be used to generalize this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call with a single `Literal` argument. For example:
|
||||
* ```
|
||||
* myPredicate(4)
|
||||
* ```
|
||||
*/
|
||||
class CallLiteral extends Call {
|
||||
CallLiteral() {
|
||||
getNumberOfArguments() = 1 and
|
||||
getArgument(0) instanceof Literal
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A chain of disjunctions where each operand is a call to the same predicate
|
||||
* using various `Literal`s. For example:
|
||||
* ```
|
||||
* myPredicate(4) or
|
||||
* myPredicate(5) or
|
||||
* myPredicate(6)
|
||||
* ```
|
||||
*/
|
||||
class DisjunctionPredicateLiteral extends DisjunctionChain {
|
||||
DisjunctionPredicateLiteral() {
|
||||
// Call to the same target
|
||||
exists(PredicateOrBuiltin target |
|
||||
forex(Formula f | f = getAnOperandRec() | f.(CallLiteral).getTarget() = target)
|
||||
)
|
||||
}
|
||||
}
|
||||
import codeql_ql.style.UseSetLiteralQuery
|
||||
|
||||
from DisjunctionChain d, string msg, int c
|
||||
where
|
||||
@@ -124,6 +24,6 @@ where
|
||||
"This formula of " + c.toString() +
|
||||
" predicate calls can be replaced with a single call on a set literal, improving readability."
|
||||
) and
|
||||
c = count(d.getAnOperandRec()) and
|
||||
c = count(d.getOperand(_)) and
|
||||
c >= 4
|
||||
select d, msg
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @name Suggest using non-extending subtype relationships.
|
||||
* @description Non-extending subtypes ("instanceof extensions") are generally preferrable to instanceof expressions in characteristic predicates.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id ql/suggest-instanceof-extension
|
||||
* @tags maintainability
|
||||
* @precision medium
|
||||
*/
|
||||
|
||||
import ql
|
||||
|
||||
InstanceOf instanceofInCharPred(Class c) {
|
||||
result = c.getCharPred().getBody()
|
||||
or
|
||||
exists(Conjunction conj |
|
||||
conj = c.getCharPred().getBody() and
|
||||
result = conj.getAnOperand()
|
||||
)
|
||||
}
|
||||
|
||||
predicate instanceofThisInCharPred(Class c, TypeExpr type) {
|
||||
exists(InstanceOf instanceOf |
|
||||
instanceOf = instanceofInCharPred(c) and
|
||||
instanceOf.getExpr() instanceof ThisAccess and
|
||||
type = instanceOf.getType()
|
||||
)
|
||||
}
|
||||
|
||||
predicate classWithInstanceofThis(Class c, TypeExpr type) {
|
||||
instanceofThisInCharPred(c, type) and
|
||||
exists(ClassPredicate classPred |
|
||||
classPred = c.getAClassPredicate() and
|
||||
exists(MemberCall call, InlineCast cast |
|
||||
call.getEnclosingPredicate() = classPred and
|
||||
cast = call.getBase() and
|
||||
cast.getBase() instanceof ThisAccess and
|
||||
cast.getTypeExpr().getResolvedType() = type.getResolvedType()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from Class c, TypeExpr type, string message
|
||||
where
|
||||
classWithInstanceofThis(c, type) and
|
||||
message = "consider defining $@ as non-extending subtype of $@"
|
||||
select c, message, c, c.getName(), type, type.getResolvedType().getName()
|
||||
@@ -13,164 +13,144 @@ nodes
|
||||
| Foo.qll:4:11:4:11 | Integer | semmle.order | 6 |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 |
|
||||
| Foo.qll:4:13:4:13 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:4:13:4:13 | ComparisonOp | semmle.order | 8 |
|
||||
| Foo.qll:4:15:4:15 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:4:15:4:15 | Integer | semmle.order | 9 |
|
||||
| Foo.qll:4:15:4:15 | Integer | semmle.order | 8 |
|
||||
| Foo.qll:6:3:6:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 10 |
|
||||
| Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 10 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 |
|
||||
| Foo.qll:6:23:6:28 | result | semmle.label | [ResultAccess] result |
|
||||
| Foo.qll:6:23:6:28 | result | semmle.order | 12 |
|
||||
| Foo.qll:6:23:6:28 | result | semmle.order | 11 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 12 |
|
||||
| Foo.qll:6:30:6:30 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:6:30:6:30 | ComparisonOp | semmle.order | 14 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 |
|
||||
| Foo.qll:6:32:6:36 | String | semmle.label | [String] String |
|
||||
| Foo.qll:6:32:6:36 | String | semmle.order | 15 |
|
||||
| Foo.qll:6:32:6:36 | String | semmle.order | 13 |
|
||||
| Foo.qll:9:1:9:5 | annotation | semmle.label | [Annotation] annotation |
|
||||
| Foo.qll:9:1:9:5 | annotation | semmle.order | 16 |
|
||||
| Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 17 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 |
|
||||
| Foo.qll:9:21:9:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 18 |
|
||||
| Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 |
|
||||
| Foo.qll:9:21:9:25 | f | semmle.label | [VarDecl] f |
|
||||
| Foo.qll:9:21:9:25 | f | semmle.order | 18 |
|
||||
| Foo.qll:9:21:9:25 | f | semmle.order | 16 |
|
||||
| Foo.qll:10:3:10:3 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:10:3:10:3 | f | semmle.order | 20 |
|
||||
| Foo.qll:10:3:10:3 | f | semmle.order | 18 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 20 |
|
||||
| Foo.qll:10:5:10:5 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:10:5:10:5 | ComparisonOp | semmle.order | 22 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 |
|
||||
| Foo.qll:10:7:10:85 | Rank | semmle.label | [Rank] Rank |
|
||||
| Foo.qll:10:7:10:85 | Rank | semmle.order | 23 |
|
||||
| Foo.qll:10:7:10:85 | Rank | semmle.order | 20 |
|
||||
| Foo.qll:10:12:10:12 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:10:12:10:12 | Integer | semmle.order | 24 |
|
||||
| Foo.qll:10:12:10:12 | Integer | semmle.order | 21 |
|
||||
| Foo.qll:10:15:10:17 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:10:15:10:17 | TypeExpr | semmle.order | 25 |
|
||||
| Foo.qll:10:15:10:17 | TypeExpr | semmle.order | 22 |
|
||||
| Foo.qll:10:15:10:23 | inner | semmle.label | [VarDecl] inner |
|
||||
| Foo.qll:10:15:10:23 | inner | semmle.order | 25 |
|
||||
| Foo.qll:10:15:10:23 | inner | semmle.order | 22 |
|
||||
| Foo.qll:10:27:10:31 | inner | semmle.label | [VarAccess] inner |
|
||||
| Foo.qll:10:27:10:31 | inner | semmle.order | 27 |
|
||||
| Foo.qll:10:27:10:31 | inner | semmle.order | 24 |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | semmle.label | [MemberCall] MemberCall |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | semmle.order | 27 |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | semmle.order | 24 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | semmle.order | 27 |
|
||||
| Foo.qll:10:44:10:44 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:10:44:10:44 | ComparisonOp | semmle.order | 30 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | semmle.order | 24 |
|
||||
| Foo.qll:10:46:10:50 | String | semmle.label | [String] String |
|
||||
| Foo.qll:10:46:10:50 | String | semmle.order | 31 |
|
||||
| Foo.qll:10:46:10:50 | String | semmle.order | 27 |
|
||||
| Foo.qll:10:54:10:58 | inner | semmle.label | [VarAccess] inner |
|
||||
| Foo.qll:10:54:10:58 | inner | semmle.order | 32 |
|
||||
| Foo.qll:10:54:10:58 | inner | semmle.order | 28 |
|
||||
| Foo.qll:10:69:10:73 | inner | semmle.label | [VarAccess] inner |
|
||||
| Foo.qll:10:69:10:73 | inner | semmle.order | 33 |
|
||||
| Foo.qll:10:69:10:73 | inner | semmle.order | 29 |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | semmle.order | 33 |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | semmle.order | 29 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 35 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 |
|
||||
| Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 36 |
|
||||
| Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 |
|
||||
| Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f |
|
||||
| Foo.qll:13:17:13:21 | f | semmle.order | 36 |
|
||||
| Foo.qll:13:17:13:21 | f | semmle.order | 32 |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | semmle.label | [PredicateCall] PredicateCall |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | semmle.order | 38 |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | semmle.order | 34 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | semmle.label | [Disjunction] Disjunction |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:9:14:9 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:14:9:14:9 | f | semmle.order | 45 |
|
||||
| Foo.qll:14:9:14:9 | f | semmle.order | 41 |
|
||||
| Foo.qll:16:3:16:7 | String | semmle.label | [String] String |
|
||||
| Foo.qll:16:3:16:7 | String | semmle.order | 46 |
|
||||
| Foo.qll:16:3:16:7 | String | semmle.order | 42 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 46 |
|
||||
| Foo.qll:16:9:16:9 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 48 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 42 |
|
||||
| Foo.qll:16:11:16:11 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:16:11:16:11 | f | semmle.order | 49 |
|
||||
| Foo.qll:16:11:16:11 | f | semmle.order | 44 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | semmle.label | [MemberCall] MemberCall |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | semmle.order | 49 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | semmle.order | 44 |
|
||||
| Foo.qll:16:22:16:22 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:16:22:16:22 | Integer | semmle.order | 51 |
|
||||
| Foo.qll:16:22:16:22 | Integer | semmle.order | 46 |
|
||||
| Foo.qll:16:25:16:25 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:16:25:16:25 | Integer | semmle.order | 52 |
|
||||
| Foo.qll:16:25:16:25 | Integer | semmle.order | 47 |
|
||||
| Foo.qll:16:28:16:28 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:16:28:16:28 | Integer | semmle.order | 53 |
|
||||
| Foo.qll:16:28:16:28 | Integer | semmle.order | 48 |
|
||||
| Foo.qll:18:3:18:3 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:18:3:18:3 | f | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:3 | f | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | semmle.label | [InlineCast] InlineCast |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | semmle.label | [MemberCall] MemberCall |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 49 |
|
||||
| Foo.qll:18:6:18:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 58 |
|
||||
| Foo.qll:18:22:18:22 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 59 |
|
||||
| Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 53 |
|
||||
| Foo.qll:18:24:18:28 | String | semmle.label | [String] String |
|
||||
| Foo.qll:18:24:18:28 | String | semmle.order | 60 |
|
||||
| Foo.qll:18:24:18:28 | String | semmle.order | 54 |
|
||||
| Foo.qll:20:3:20:3 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:20:3:20:3 | f | semmle.order | 61 |
|
||||
| Foo.qll:20:3:20:3 | f | semmle.order | 55 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | semmle.label | [InlineCast] InlineCast |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | semmle.order | 61 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | semmle.order | 55 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 61 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 55 |
|
||||
| Foo.qll:20:6:20:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 64 |
|
||||
| Foo.qll:20:11:20:11 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 65 |
|
||||
| Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 58 |
|
||||
| Foo.qll:20:13:20:13 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:20:13:20:13 | f | semmle.order | 66 |
|
||||
| Foo.qll:20:13:20:13 | f | semmle.order | 59 |
|
||||
| Foo.qll:22:3:22:3 | f | semmle.label | [VarAccess] f |
|
||||
| Foo.qll:22:3:22:3 | f | semmle.order | 67 |
|
||||
| Foo.qll:22:3:22:3 | f | semmle.order | 60 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 67 |
|
||||
| Foo.qll:22:5:22:5 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 69 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 60 |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.label | [FullAggregate[any]] FullAggregate[any] |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.order | 70 |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.order | 62 |
|
||||
| Foo.qll:22:11:22:13 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
|
||||
| Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 71 |
|
||||
| Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 63 |
|
||||
| Foo.qll:22:11:22:15 | f | semmle.label | [VarDecl] f |
|
||||
| Foo.qll:22:11:22:15 | f | semmle.order | 71 |
|
||||
| Foo.qll:22:11:22:15 | f | semmle.order | 63 |
|
||||
| Foo.qll:24:3:24:3 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:24:3:24:3 | Integer | semmle.order | 73 |
|
||||
| Foo.qll:24:3:24:3 | Integer | semmle.order | 65 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 73 |
|
||||
| Foo.qll:24:5:24:5 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 75 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 65 |
|
||||
| Foo.qll:24:7:24:7 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:24:7:24:7 | Integer | semmle.order | 76 |
|
||||
| Foo.qll:24:7:24:7 | Integer | semmle.order | 67 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | semmle.label | [AddExpr] AddExpr |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | semmle.order | 76 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | semmle.order | 67 |
|
||||
| Foo.qll:24:12:24:12 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:24:12:24:12 | Integer | semmle.order | 78 |
|
||||
| Foo.qll:24:12:24:12 | Integer | semmle.order | 69 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | semmle.label | [AddExpr] AddExpr |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | semmle.order | 78 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | semmle.order | 69 |
|
||||
| Foo.qll:24:17:24:17 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:24:17:24:17 | Integer | semmle.order | 80 |
|
||||
| Foo.qll:24:17:24:17 | Integer | semmle.order | 71 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | semmle.label | [AddExpr] AddExpr |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | semmle.order | 80 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | semmle.order | 71 |
|
||||
| Foo.qll:24:21:24:21 | Integer | semmle.label | [Integer] Integer |
|
||||
| Foo.qll:24:21:24:21 | Integer | semmle.order | 82 |
|
||||
| Foo.qll:24:21:24:21 | Integer | semmle.order | 73 |
|
||||
| Foo.qll:26:3:26:6 | Boolean | semmle.label | [Boolean] Boolean |
|
||||
| Foo.qll:26:3:26:6 | Boolean | semmle.order | 83 |
|
||||
| Foo.qll:26:3:26:6 | Boolean | semmle.order | 74 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 83 |
|
||||
| Foo.qll:26:8:26:8 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp |
|
||||
| Foo.qll:26:8:26:8 | ComparisonOp | semmle.order | 85 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 74 |
|
||||
| Foo.qll:26:10:26:14 | Boolean | semmle.label | [Boolean] Boolean |
|
||||
| Foo.qll:26:10:26:14 | Boolean | semmle.order | 86 |
|
||||
| Foo.qll:26:10:26:14 | Boolean | semmle.order | 76 |
|
||||
| file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs |
|
||||
| file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs |
|
||||
| file://:0:0:0:0 | acos | semmle.label | [BuiltinPredicate] acos |
|
||||
@@ -253,183 +233,163 @@ nodes
|
||||
| file://:0:0:0:0 | trim | semmle.label | [BuiltinPredicate] trim |
|
||||
| file://:0:0:0:0 | ulp | semmle.label | [BuiltinPredicate] ulp |
|
||||
| printAst.ql:1:1:1:28 | Import | semmle.label | [Import] Import |
|
||||
| printAst.ql:1:1:1:28 | Import | semmle.order | 87 |
|
||||
| printAst.ql:1:1:1:28 | Import | semmle.order | 77 |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | semmle.label | [TopLevel] TopLevel |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 87 |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 77 |
|
||||
edges
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.label | getAClass() |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | getAPredicate() |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 17 |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | getAPredicate() |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 35 |
|
||||
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | getClassPredicate(_) |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 10 |
|
||||
| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 |
|
||||
| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() |
|
||||
| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:13:4:13 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:13:4:13 | ComparisonOp | semmle.order | 8 |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.label | getRightOperand() |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 9 |
|
||||
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 10 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 12 |
|
||||
| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 12 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:30:6:30 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:30:6:30 | ComparisonOp | semmle.order | 14 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 11 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 15 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 13 |
|
||||
| Foo.qll:9:1:9:5 | annotation | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
|
||||
| Foo.qll:9:1:9:5 | annotation | Foo.qll:9:1:9:5 | annotation | semmle.order | 16 |
|
||||
| Foo.qll:9:1:9:5 | annotation | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 16 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 18 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 20 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 |
|
||||
| Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 18 |
|
||||
| Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.order | 20 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:5:10:5 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:5:10:5 | ComparisonOp | semmle.order | 22 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.order | 18 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:7:10:85 | Rank | semmle.label | getRightOperand() |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:7:10:85 | Rank | semmle.order | 23 |
|
||||
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:7:10:85 | Rank | semmle.order | 20 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:12:10:12 | Integer | semmle.label | getRankExpr() |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:12:10:12 | Integer | semmle.order | 24 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:12:10:12 | Integer | semmle.order | 21 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:15:10:23 | inner | semmle.label | getArgument(_) |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:15:10:23 | inner | semmle.order | 25 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:15:10:23 | inner | semmle.order | 22 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:27:10:50 | ComparisonFormula | semmle.label | getRange() |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:27:10:50 | ComparisonFormula | semmle.order | 27 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:27:10:50 | ComparisonFormula | semmle.order | 24 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:54:10:58 | inner | semmle.label | getExpr(_) |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:54:10:58 | inner | semmle.order | 32 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:54:10:58 | inner | semmle.order | 28 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:69:10:84 | MemberCall | semmle.label | getOrderBy(_) |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 33 |
|
||||
| Foo.qll:10:7:10:85 | Rank | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 29 |
|
||||
| Foo.qll:10:15:10:23 | inner | Foo.qll:10:15:10:17 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:10:15:10:23 | inner | Foo.qll:10:15:10:17 | TypeExpr | semmle.order | 25 |
|
||||
| Foo.qll:10:15:10:23 | inner | Foo.qll:10:15:10:17 | TypeExpr | semmle.order | 22 |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | Foo.qll:10:27:10:31 | inner | semmle.label | getBase() |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | Foo.qll:10:27:10:31 | inner | semmle.order | 27 |
|
||||
| Foo.qll:10:27:10:42 | MemberCall | Foo.qll:10:27:10:31 | inner | semmle.order | 24 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:27:10:42 | MemberCall | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:27:10:42 | MemberCall | semmle.order | 27 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:44:10:44 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:44:10:44 | ComparisonOp | semmle.order | 30 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:27:10:42 | MemberCall | semmle.order | 24 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.label | getRightOperand() |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 31 |
|
||||
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 27 |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 33 |
|
||||
| Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 29 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 36 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 36 |
|
||||
| Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.order | 45 |
|
||||
| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.order | 41 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:14:3:14:10 | PredicateCall | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:14:3:14:10 | PredicateCall | semmle.order | 38 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:14:3:14:10 | PredicateCall | semmle.order | 34 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 46 |
|
||||
| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 42 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:14:3:16:29 | Disjunction | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:14:3:16:29 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:14:3:16:29 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 54 |
|
||||
| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 49 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:14:3:18:28 | Disjunction | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:14:3:18:28 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:14:3:18:28 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 61 |
|
||||
| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 55 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:14:3:20:13 | Disjunction | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:14:3:20:13 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:14:3:20:13 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 67 |
|
||||
| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 60 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:14:3:22:16 | Disjunction | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:14:3:22:16 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:14:3:22:16 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 73 |
|
||||
| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 65 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:14:3:24:23 | Disjunction | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 38 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 34 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.label | getAnOperand() |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 83 |
|
||||
| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 74 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.order | 46 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:9:16:9 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 48 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.order | 42 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.label | getRightOperand() |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.order | 49 |
|
||||
| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.order | 44 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.label | getBase() |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.order | 49 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.order | 44 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.label | getArgument(_) |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.order | 51 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.order | 46 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.label | getArgument(_) |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.order | 52 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.order | 47 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.label | getArgument(_) |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.order | 53 |
|
||||
| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.order | 48 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.label | getBase() |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 58 |
|
||||
| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 53 |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.label | getBase() |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.order | 54 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:22:18:22 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 59 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.order | 49 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.label | getRightOperand() |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.order | 60 |
|
||||
| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.order | 54 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.label | getBase() |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.order | 61 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.order | 55 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 64 |
|
||||
| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 58 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.order | 61 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:11:20:11 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 65 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.order | 55 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.label | getRightOperand() |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.order | 66 |
|
||||
| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.order | 59 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.order | 67 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:5:22:5 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 69 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.order | 60 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.label | getRightOperand() |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.order | 70 |
|
||||
| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | FullAggregate[any] | semmle.order | 62 |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | Foo.qll:22:11:22:15 | f | semmle.label | getArgument(_) |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | Foo.qll:22:11:22:15 | f | semmle.order | 71 |
|
||||
| Foo.qll:22:7:22:16 | FullAggregate[any] | Foo.qll:22:11:22:15 | f | semmle.order | 63 |
|
||||
| Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.label | getTypeExpr() |
|
||||
| Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 71 |
|
||||
| Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 63 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.order | 73 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:5:24:5 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 75 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.order | 65 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.label | getRightOperand() |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.order | 76 |
|
||||
| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.order | 67 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.order | 76 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.order | 67 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.label | getRightOperand() |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.order | 78 |
|
||||
| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.order | 69 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.order | 78 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.order | 69 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.label | getRightOperand() |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.order | 80 |
|
||||
| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.order | 71 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.order | 80 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.order | 71 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.label | getRightOperand() |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.order | 82 |
|
||||
| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.order | 73 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.label | getLeftOperand() |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.order | 83 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:8:26:8 | ComparisonOp | semmle.label | getOperator() |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:8:26:8 | ComparisonOp | semmle.order | 85 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.order | 74 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.label | getRightOperand() |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.order | 86 |
|
||||
| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.order | 76 |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAnImport() |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 87 |
|
||||
| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 77 |
|
||||
graphProperties
|
||||
| semmle.graphKind | tree |
|
||||
|
||||
167
ql/test/queries/performance/VarUnusedInDisjunct/Test.qll
Normal file
167
ql/test/queries/performance/VarUnusedInDisjunct/Test.qll
Normal file
@@ -0,0 +1,167 @@
|
||||
import ql
|
||||
|
||||
class Big = Expr;
|
||||
|
||||
class Small extends boolean {
|
||||
Small() { this = [true, false] }
|
||||
}
|
||||
|
||||
class MyStr extends string {
|
||||
MyStr() { this = ["foo", "bar"] }
|
||||
}
|
||||
|
||||
predicate bad1(Big b) {
|
||||
b.toString().matches("%foo")
|
||||
or
|
||||
any()
|
||||
}
|
||||
|
||||
int bad2() {
|
||||
exists(Big big, Small small |
|
||||
result = big.toString().toInt()
|
||||
or
|
||||
result = small.toString().toInt()
|
||||
)
|
||||
}
|
||||
|
||||
float bad3(Big t) {
|
||||
result = [1 .. 10].toString().toFloat() or
|
||||
result = [11 .. 20].toString().toFloat() or
|
||||
result = t.toString().toFloat() or
|
||||
result = [21 .. 30].toString().toFloat()
|
||||
}
|
||||
|
||||
string good1(Big t) {
|
||||
(
|
||||
result = t.toString()
|
||||
or
|
||||
result instanceof MyStr // <- t unused here, but that's ok because of the conjunct that binds t.
|
||||
) and
|
||||
t.toString().regexpMatch(".*foo")
|
||||
}
|
||||
|
||||
predicate helper(Big a, Big b) {
|
||||
a = b and
|
||||
a.toString().matches("%foo")
|
||||
}
|
||||
|
||||
predicate bad4(Big fromType, Big toType) {
|
||||
helper(fromType, toType)
|
||||
or
|
||||
fromType.toString().matches("%foo")
|
||||
or
|
||||
helper(toType, fromType)
|
||||
}
|
||||
|
||||
predicate good2(Big t) {
|
||||
exists(Small other |
|
||||
t.toString().matches("%foo")
|
||||
or
|
||||
other.toString().matches("%foo") // <- t unused here, but that's ok because of the conjunct (exists) that binds t.
|
||||
|
|
||||
t.toString().regexpMatch(".*foo")
|
||||
)
|
||||
}
|
||||
|
||||
predicate mixed1(Big good, Small small) {
|
||||
good.toString().matches("%foo")
|
||||
or
|
||||
good =
|
||||
any(Big bad |
|
||||
small.toString().matches("%foo") and
|
||||
// the use of good is fine, the comparison futher up binds it.
|
||||
// the same is not true for bad.
|
||||
(bad.toString().matches("%foo") or good.toString().regexpMatch("foo.*")) and
|
||||
small.toString().regexpMatch(".*foo")
|
||||
)
|
||||
}
|
||||
|
||||
newtype OtherSmall =
|
||||
Small1() or
|
||||
Small2(boolean b) { b = true } or
|
||||
Small3(boolean b, Small o) {
|
||||
b = true and
|
||||
o.toString().matches("%foo")
|
||||
}
|
||||
|
||||
predicate good3(OtherSmall small) {
|
||||
small = Small1()
|
||||
or
|
||||
1 = 1
|
||||
}
|
||||
|
||||
predicate good4(Big big, Small small) {
|
||||
big.toString().matches("%foo")
|
||||
or
|
||||
// assignment to small type, intentional cartesian product
|
||||
small = any(Small s | s.toString().matches("%foo"))
|
||||
}
|
||||
|
||||
predicate good5(Big bb, Big v, boolean certain) {
|
||||
exists(Big read |
|
||||
read = bb and
|
||||
read = v and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
v =
|
||||
any(Big lsv |
|
||||
lsv.getEnclosingPredicate() = bb.(Expr).getEnclosingPredicate() and
|
||||
(lsv.toString().matches("%foo") or v.toString().matches("%foo")) and
|
||||
certain = false
|
||||
)
|
||||
}
|
||||
|
||||
predicate bad5(Big bb) { if none() then bb.toString().matches("%foo") else any() }
|
||||
|
||||
pragma[inline]
|
||||
predicate good5(Big a, Big b) {
|
||||
// fine. Assumes it's used somewhere where `a` and `b` are bound.
|
||||
b = any(Big bb | bb.toString().matches("%foo"))
|
||||
or
|
||||
a = any(Big bb | bb.toString().matches("%foo"))
|
||||
}
|
||||
|
||||
predicate bad6(Big a) {
|
||||
(
|
||||
a.toString().matches("%foo") // bad
|
||||
or
|
||||
any()
|
||||
) and
|
||||
(
|
||||
a.toString().matches("%foo") // also bad
|
||||
or
|
||||
any()
|
||||
)
|
||||
}
|
||||
|
||||
predicate good6(Big a) {
|
||||
a.toString().matches("%foo") and
|
||||
(
|
||||
a.toString().matches("%foo") // good, `a` is bound on the branch of the conjunction.
|
||||
or
|
||||
any()
|
||||
)
|
||||
}
|
||||
|
||||
predicate good7() {
|
||||
exists(Big l, Big r |
|
||||
l.toString().matches("%foo1") and
|
||||
r.toString().matches("%foo2")
|
||||
or
|
||||
l.toString().matches("%foo3") and
|
||||
r.toString().matches("%foo4")
|
||||
|
|
||||
not (l.toString().regexpMatch("%foo5") or r.toString().regexpMatch("%foo6")) and
|
||||
(l.toString().regexpMatch("%foo7") or r.toString().regexpMatch("%foo8"))
|
||||
)
|
||||
}
|
||||
|
||||
// TOOD: Next test, this one is
|
||||
string good8(int bitSize) {
|
||||
if bitSize != 0
|
||||
then bitSize = 1 and result = bitSize.toString()
|
||||
else (
|
||||
if 1 = 0 then result = "foo" else result = "bar"
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
| Test.qll:14:3:16:7 | Disjunction | The variable b is only used in one side of disjunct. |
|
||||
| Test.qll:21:5:23:37 | Disjunction | The variable big is only used in one side of disjunct. |
|
||||
| Test.qll:28:3:30:33 | Disjunction | The variable t is only used in one side of disjunct. |
|
||||
| Test.qll:49:3:53:26 | Disjunction | The variable toType is only used in one side of disjunct. |
|
||||
| Test.qll:74:8:74:77 | Disjunction | The variable bad is only used in one side of disjunct. |
|
||||
| Test.qll:115:26:115:80 | IfFormula | The variable bb is only used in one side of disjunct. |
|
||||
| Test.qll:127:5:129:9 | Disjunction | The variable a is only used in one side of disjunct. |
|
||||
| Test.qll:132:5:134:9 | Disjunction | The variable a is only used in one side of disjunct. |
|
||||
@@ -0,0 +1 @@
|
||||
queries/performance/VarUnusedInDisjunct.ql
|
||||
Reference in New Issue
Block a user