Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 0 additions & 101 deletions java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,6 @@ private import SSA
private import RangeUtils
private import RangeAnalysis

/** Gets an expression that might have the value `i`. */
deprecated private Expr exprWithIntValue(int i) {
result.(ConstantIntegerExpr).getIntValue() = i or
result.(ChooseExpr).getAResultExpr() = exprWithIntValue(i)
}

/**
* An expression for which the predicate `integerGuard` is relevant.
* This includes `VarRead` and `MethodCall`.
*/
deprecated class IntComparableExpr extends Expr {
IntComparableExpr() { this instanceof VarRead or this instanceof MethodCall }

/** Gets an integer that is directly assigned to the expression in case of a variable; or zero. */
deprecated int relevantInt() {
exists(SsaExplicitUpdate ssa, SsaSourceVariable v |
this = v.getAnAccess() and
ssa.getSourceVariable() = v and
ssa.getDefiningExpr().(VariableAssign).getSource() = exprWithIntValue(result)
)
or
result = 0
}
}

/**
* Holds if `comp` evaluating to `branch` ensures that `e1` is less than `e2`.
* When `strict` is true, `e1` is strictly less than `e2`, otherwise it is less
Expand Down Expand Up @@ -111,79 +86,3 @@ Expr nonZeroGuard(Expr e, boolean branch) {
upper = false and val > 0 // e >= val > 0 ==> e != 0
)
}

/**
* DEPRECATED.
*
* An expression that directly tests whether a given expression is equal to `k` or not.
* The set of `k`s is restricted to those that are relevant for the expression or
* have a direct comparison with the expression.
*
* If `result` evaluates to `branch`, then `e` is guaranteed to be equal to `k` if `is_k`
* is true, and different from `k` if `is_k` is false.
*/
pragma[nomagic]
deprecated Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
exists(EqualityTest eqtest, boolean polarity |
eqtest = result and
eqtest.hasOperands(e, any(ConstantIntegerExpr c | c.getIntValue() = k)) and
polarity = eqtest.polarity() and
(
branch = true and is_k = polarity
or
branch = false and is_k = polarity.booleanNot()
)
)
or
exists(int val, boolean upper |
rangeGuard(result, branch, e, val, upper) and
k = e.relevantInt() and
is_k = false
|
upper = true and val < k // e <= val < k ==> e != k
or
upper = false and val > k // e >= val > k ==> e != k
)
}

/**
* DEPRECATED: Use `rangeGuard` instead.
*
* A guard that splits the values of a variable into one range with an upper bound of `k-1`
* and one with a lower bound of `k`.
*
* If `branch_with_lower_bound_k` is true then `result` is equivalent to `k <= x`
* and if it is false then `result` is equivalent to `k > x`.
*/
deprecated Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) {
exists(ComparisonExpr comp, ConstantIntegerExpr c, int val |
comp = result and
comp.hasOperands(x, c) and
c.getIntValue() = val and
x.getVariable().getType() instanceof IntegralType
|
// c < x
comp.getLesserOperand() = c and
comp.isStrict() and
branch_with_lower_bound_k = true and
val + 1 = k
or
// c <= x
comp.getLesserOperand() = c and
not comp.isStrict() and
branch_with_lower_bound_k = true and
val = k
or
// x < c
comp.getGreaterOperand() = c and
comp.isStrict() and
branch_with_lower_bound_k = false and
val = k
or
// x <= c
comp.getGreaterOperand() = c and
not comp.isStrict() and
branch_with_lower_bound_k = false and
val + 1 = k
)
}
240 changes: 0 additions & 240 deletions java/ql/lib/semmle/code/java/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -188,178 +188,6 @@ class SsaImplicitQualifierDefinition extends SsaImplicitWrite {
*/
VarRead ssaGetAFirstUse(SsaDefinition def) { firstUse(def, result) }

/**
* DEPRECATED: use `SsaDefinition` instead.
*
* An SSA variable.
*/
deprecated class SsaVariable extends Definition {
/** Gets the SSA source variable underlying this SSA variable. */
SsaSourceVariable getSourceVariable() { result = super.getSourceVariable() }

/**
* DEPRECATED: Use `getControlFlowNode()` instead.
*
* Gets the `ControlFlowNode` at which this SSA variable is defined.
*/
pragma[nomagic]
deprecated ControlFlowNode getCfgNode() {
exists(BasicBlock bb, int i |
this.definesAt(_, bb, i) and
// phi nodes are inserted at position `-1`
result = bb.getNode(0.maximum(i))
)
}

/** Gets a textual representation of this SSA variable. */
string toString() { none() }

/** Gets the source location for this element. */
Location getLocation() { result = this.getCfgNode().getLocation() }

/** Gets the `BasicBlock` in which this SSA variable is defined. */
BasicBlock getBasicBlock() { result = super.getBasicBlock() }

/**
* DEPRECATED: Use `getARead()` instead.
*
* Gets an access of this SSA variable.
*/
deprecated VarRead getAUse() { result = getAUse(this) }

/**
* DEPRECATED: Use `ssaGetAFirstUse(SsaDefinition)` instead.
*
* Gets an access of the SSA source variable underlying this SSA variable
* that can be reached from this SSA variable without passing through any
* other uses, but potentially through phi nodes and uncertain implicit
* updates.
*
* Subsequent uses can be found by following the steps defined by
* `adjacentUseUse`.
*/
deprecated VarRead getAFirstUse() { firstUse(this, result) }

/** Holds if this SSA variable is live at the end of `b`. */
predicate isLiveAtEndOfBlock(BasicBlock b) { ssaDefReachesEndOfBlock(b, this) }

/**
* DEPRECATED.
*
* Gets an SSA variable whose value can flow to this one in one step. This
* includes inputs to phi nodes, the prior definition of uncertain updates,
* and the captured ssa variable for a closure variable.
*/
deprecated SsaVariable getAPhiInputOrPriorDef() {
result = this.(SsaPhiNode).getAPhiInput() or
result = this.(SsaUncertainImplicitUpdate).getPriorDef() or
this.(SsaImplicitInit).captures(result)
}

/**
* DEPRECATED: Use `SsaCapturedDefinition::getAnUltimateCapturedDefinition()`
* and/or `SsaDefinition::getAnUltimateDefinition()` instead.
*
* Gets a definition that ultimately defines this variable and is not itself a phi node.
*/
deprecated SsaVariable getAnUltimateDefinition() {
result = this.getAPhiInputOrPriorDef*() and not result instanceof SsaPhiNode
}
}

/**
* DEPRECATED: use `SsaWriteDefinition` instead.
*
* An SSA variable that either explicitly or implicitly updates the variable.
*/
deprecated class SsaUpdate extends SsaVariable instanceof WriteDefinition {
SsaUpdate() { not this instanceof SsaImplicitInit }
}

/**
* DEPRECATED: Use `SsaExplicitWrite` instead.
*
* An SSA variable that is defined by a `VariableUpdate`.
*/
deprecated class SsaExplicitUpdate extends SsaUpdate {
private VariableUpdate upd;

SsaExplicitUpdate() { ssaExplicitUpdate(this, upd) }

override string toString() { result = "SSA def(" + this.getSourceVariable() + ")" }

/** Gets the `VariableUpdate` defining the SSA variable. */
VariableUpdate getDefiningExpr() { result = upd }
}

/**
* DEPRECATED: Use `SsaImplicitWrite` instead.
*
* An SSA variable that represents any sort of implicit update. This can be a
* `Call` that might reach a non-local update of the field, an explicit or
* implicit update of the qualifier of the field, or the implicit update that
* occurs just prior to a `FieldRead` of an untracked field.
*/
deprecated class SsaImplicitUpdate extends SsaUpdate {
SsaImplicitUpdate() { not this instanceof SsaExplicitUpdate }

override string toString() {
result = "SSA impl upd[" + this.getKind() + "](" + this.getSourceVariable() + ")"
}

private predicate hasExplicitQualifierUpdate() {
exists(SsaUpdate qdef, BasicBlock bb, int i |
qdef.definesAt(this.getSourceVariable().getQualifier(), bb, i) and
this.definesAt(_, bb, i) and
not qdef instanceof SsaUncertainImplicitUpdate
)
}

private predicate hasImplicitQualifierUpdate() {
exists(SsaUncertainImplicitUpdate qdef, BasicBlock bb, int i |
qdef.definesAt(this.getSourceVariable().getQualifier(), bb, i) and
this.definesAt(_, bb, i)
)
}

private string getKind() {
this.hasExplicitQualifierUpdate() and
result = "explicit qualifier" // -> SSA qualifier def
or
if this.hasImplicitQualifierUpdate()
then
if isNonLocal(this)
then result = "nonlocal + nonlocal qualifier" // -> SSA qualifier def
else result = "nonlocal qualifier" // -> SSA qualifier def
else (
isNonLocal(this) and result = "nonlocal" // -> SSA call def
)
}

/**
* DEPRECATED: Use `SsaImplicitCallDefinition.getANonLocalUpdate()` instead.
*
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
*/
overlay[global]
deprecated FieldWrite getANonLocalUpdate() { result = getANonLocalUpdate(this) }

/**
* DEPRECATED: Use `SsaImplicitQualifierDefinition` instead.
*
* Holds if this ssa variable might change the value to something unknown.
*
* Examples include updates that might change the value of the qualifier, or
* reads from untracked variables, for example those where the field or one
* of its qualifiers is volatile.
*/
deprecated predicate assignsUnknownValue() {
this.hasExplicitQualifierUpdate()
or
this.hasImplicitQualifierUpdate()
}
}

private predicate hasQualifierUpdate(SsaImplicitWrite def) {
exists(SsaWriteDefinition qdef, BasicBlock bb, int i |
qdef.definesAt(def.getSourceVariable().getQualifier(), bb, i) and
Expand All @@ -384,74 +212,6 @@ private predicate isNonLocalImpl(SsaImplicitWrite calldef) { exists(getANonLocal

private predicate isNonLocal(SsaImplicitWrite calldef) = forceLocal(isNonLocalImpl/1)(calldef)

/**
* DEPRECATED: Use `SsaUncertainWrite` instead.
*
* An SSA variable that represents an uncertain implicit update of the value.
* This is a `Call` that might reach a non-local update of the field or one of
* its qualifiers.
*/
deprecated class SsaUncertainImplicitUpdate extends SsaImplicitUpdate {
SsaUncertainImplicitUpdate() { ssaUncertainImplicitUpdate(this) }

/**
* DEPRECATED: Use `getPriorDefinition()` instead.
*
* Gets the immediately preceding definition. Since this update is uncertain
* the value from the preceding definition might still be valid.
*/
deprecated SsaVariable getPriorDef() { ssaDefReachesUncertainDef(result, this) }
}

/**
* DEPRECATED: Use `SsaParameterInit`, `SsaImplicitEntryDefinition`, or `SsaCapturedDefinition` instead.
*
* An SSA variable that is defined by its initial value in the callable. This
* includes initial values of parameters, fields, and closure variables.
*/
deprecated class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
SsaImplicitInit() { ssaImplicitInit(this) }

override string toString() { result = "SSA init(" + this.getSourceVariable() + ")" }

/** Holds if this is a closure variable that captures the value of `capturedvar`. */
predicate captures(SsaVariable capturedvar) { captures(this, capturedvar) }

/**
* DEPRECATED: Use `SsaParameterInit::getParameter()` instead.
*
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
*/
deprecated predicate isParameterDefinition(Parameter p) {
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody().getControlFlowNode() = this.getCfgNode()
}
}

/**
* DEPRECATED: Use `SsaPhiDefinition` instead.
*
* An SSA phi node.
*/
deprecated class SsaPhiNode extends SsaVariable instanceof PhiNode {
override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" }

/**
* DEPRECATED: Use `getAnInput()` instead.
*
* Gets an input to the phi node defining the SSA variable.
*/
deprecated SsaVariable getAPhiInput() { this.hasInputFromBlock(result, _) }

/** Gets an input to the phi node defining the SSA variable. */
SsaVariable getAnInput() { this.hasInputFromBlock(result, _) }

/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
predicate hasInputFromBlock(SsaVariable inp, BasicBlock bb) {
phiHasInputFromBlock(this, inp, bb)
}
}

private class RefTypeCastingExpr extends CastingExpr {
RefTypeCastingExpr() {
this.getType() instanceof RefType and
Expand Down
Loading
Loading