mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Guards: Align the SSA signature with the one from shared SSA.
This commit is contained in:
@@ -380,18 +380,20 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
|
|||||||
GuardsInput::Expr getARead() { result = this.getAUse().getDef() }
|
GuardsInput::Expr getARead() { result = this.getAUse().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaWriteDefinition extends SsaDefinition instanceof ExplicitDefinition {
|
class SsaExplicitWrite extends SsaDefinition instanceof ExplicitDefinition {
|
||||||
GuardsInput::Expr getDefinition() { result = super.getAssignedInstruction() }
|
GuardsInput::Expr getValue() { result = super.getAssignedInstruction() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPhiNode extends SsaDefinition instanceof PhiNode {
|
class SsaPhiDefinition extends SsaDefinition instanceof PhiNode {
|
||||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||||
super.hasInputFromBlock(inp, bb)
|
super.hasInputFromBlock(inp, bb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate parameterDefinition(GuardsInput::Parameter p, SsaDefinition def) {
|
class SsaParameterInit extends SsaDefinition {
|
||||||
def.isParameterDefinition(p)
|
SsaParameterInit() { this.isParameterDefinition(_) }
|
||||||
|
|
||||||
|
GuardsInput::Parameter getParameter() { this.isParameterDefinition(result) }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate additionalImpliesStep(
|
predicate additionalImpliesStep(
|
||||||
|
|||||||
@@ -207,18 +207,18 @@ private module LogicInput implements GuardsImpl::LogicInputSig {
|
|||||||
Expr getARead() { super.getARead() = result }
|
Expr getARead() { super.getARead() = result }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaWriteDefinition extends SsaDefinition instanceof Ssa::ExplicitDefinition {
|
class SsaExplicitWrite extends SsaDefinition instanceof Ssa::ExplicitDefinition {
|
||||||
Expr getDefinition() { result = super.getADefinition().getSource() }
|
Expr getValue() { result = super.getADefinition().getSource() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPhiNode extends SsaDefinition instanceof Ssa::PhiNode {
|
class SsaPhiDefinition extends SsaDefinition instanceof Ssa::PhiNode {
|
||||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||||
super.hasInputFromBlock(inp, bb)
|
super.hasInputFromBlock(inp, bb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate parameterDefinition(Parameter p, SsaDefinition def) {
|
class SsaParameterInit extends SsaDefinition instanceof Ssa::ImplicitParameterDefinition {
|
||||||
def.(Ssa::ImplicitParameterDefinition).getParameter() = p
|
Parameter getParameter() { result = super.getParameter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate additionalNullCheck(GuardsImpl::PreGuard guard, GuardValue val, Expr e, boolean isNull) {
|
predicate additionalNullCheck(GuardsImpl::PreGuard guard, GuardValue val, Expr e, boolean isNull) {
|
||||||
|
|||||||
@@ -415,21 +415,21 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
|
|||||||
GuardsInput::Expr getARead() { result = this.getAUse() }
|
GuardsInput::Expr getARead() { result = this.getAUse() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaWriteDefinition extends SsaDefinition instanceof BaseSsaUpdate {
|
class SsaExplicitWrite extends SsaDefinition instanceof BaseSsaUpdate {
|
||||||
GuardsInput::Expr getDefinition() {
|
GuardsInput::Expr getValue() {
|
||||||
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
||||||
super.getDefiningExpr().(AssignOp) = result
|
super.getDefiningExpr().(AssignOp) = result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPhiNode extends SsaDefinition instanceof BaseSsaPhiNode {
|
class SsaPhiDefinition extends SsaDefinition instanceof BaseSsaPhiNode {
|
||||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||||
super.hasInputFromBlock(inp, bb)
|
super.hasInputFromBlock(inp, bb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate parameterDefinition(Parameter p, SsaDefinition def) {
|
class SsaParameterInit extends SsaDefinition instanceof BaseSsaImplicitInit {
|
||||||
def.(BaseSsaImplicitInit).isParameterDefinition(p)
|
Parameter getParameter() { super.isParameterDefinition(result) }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
||||||
@@ -446,21 +446,21 @@ private module LogicInput_v2 implements GuardsImpl::LogicInputSig {
|
|||||||
GuardsInput::Expr getARead() { result = this.getAUse() }
|
GuardsInput::Expr getARead() { result = this.getAUse() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaWriteDefinition extends SsaDefinition instanceof SSA::SsaExplicitUpdate {
|
class SsaExplicitWrite extends SsaDefinition instanceof SSA::SsaExplicitUpdate {
|
||||||
GuardsInput::Expr getDefinition() {
|
GuardsInput::Expr getValue() {
|
||||||
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
||||||
super.getDefiningExpr().(AssignOp) = result
|
super.getDefiningExpr().(AssignOp) = result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPhiNode extends SsaDefinition instanceof SSA::SsaPhiNode {
|
class SsaPhiDefinition extends SsaDefinition instanceof SSA::SsaPhiNode {
|
||||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||||
super.hasInputFromBlock(inp, bb)
|
super.hasInputFromBlock(inp, bb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate parameterDefinition(Parameter p, SsaDefinition def) {
|
class SsaParameterInit extends SsaDefinition instanceof SSA::SsaImplicitInit {
|
||||||
def.(SSA::SsaImplicitInit).isParameterDefinition(p)
|
Parameter getParameter() { super.isParameterDefinition(result) }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
||||||
|
|||||||
@@ -536,16 +536,18 @@ module Make<
|
|||||||
Location getLocation();
|
Location getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaWriteDefinition extends SsaDefinition {
|
class SsaExplicitWrite extends SsaDefinition {
|
||||||
Expr getDefinition();
|
Expr getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPhiNode extends SsaDefinition {
|
class SsaPhiDefinition extends SsaDefinition {
|
||||||
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
|
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
|
||||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb);
|
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate parameterDefinition(Parameter p, SsaDefinition def);
|
class SsaParameterInit extends SsaDefinition {
|
||||||
|
Parameter getParameter();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `guard` evaluating to `val` ensures that:
|
* Holds if `guard` evaluating to `val` ensures that:
|
||||||
@@ -594,7 +596,7 @@ module Make<
|
|||||||
* logical inferences from `phi` to `guard` trivial and irrelevant.
|
* logical inferences from `phi` to `guard` trivial and irrelevant.
|
||||||
*/
|
*/
|
||||||
private predicate guardControlsPhiBranch(
|
private predicate guardControlsPhiBranch(
|
||||||
Guard guard, GuardValue v, SsaPhiNode phi, SsaDefinition inp
|
Guard guard, GuardValue v, SsaPhiDefinition phi, SsaDefinition inp
|
||||||
) {
|
) {
|
||||||
exists(BasicBlock bbPhi |
|
exists(BasicBlock bbPhi |
|
||||||
phi.hasInputFromBlock(inp, _) and
|
phi.hasInputFromBlock(inp, _) and
|
||||||
@@ -615,10 +617,12 @@ module Make<
|
|||||||
*
|
*
|
||||||
* This makes `phi` similar to the conditional `phi = guard==v ? input : ...`.
|
* This makes `phi` similar to the conditional `phi = guard==v ? input : ...`.
|
||||||
*/
|
*/
|
||||||
private predicate guardDeterminesPhiInput(Guard guard, GuardValue v, SsaPhiNode phi, Expr input) {
|
private predicate guardDeterminesPhiInput(
|
||||||
exists(GuardValue dv, SsaWriteDefinition inp |
|
Guard guard, GuardValue v, SsaPhiDefinition phi, Expr input
|
||||||
|
) {
|
||||||
|
exists(GuardValue dv, SsaExplicitWrite inp |
|
||||||
guardControlsPhiBranch(guard, v, phi, inp) and
|
guardControlsPhiBranch(guard, v, phi, inp) and
|
||||||
inp.getDefinition() = input and
|
inp.getValue() = input and
|
||||||
dv = v.getDualValue() and
|
dv = v.getDualValue() and
|
||||||
forall(SsaDefinition other | phi.hasInputFromBlock(other, _) and other != inp |
|
forall(SsaDefinition other | phi.hasInputFromBlock(other, _) and other != inp |
|
||||||
guardControlsPhiBranch(guard, dv, phi, other)
|
guardControlsPhiBranch(guard, dv, phi, other)
|
||||||
@@ -644,7 +648,7 @@ module Make<
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
// An expression `x = ...` can be considered as a read of `x`.
|
// An expression `x = ...` can be considered as a read of `x`.
|
||||||
guard.(IdExpr).getEqualChildExpr() = def.(SsaWriteDefinition).getDefinition()
|
guard.(IdExpr).getEqualChildExpr() = def.(SsaExplicitWrite).getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate valueStep(Expr e1, Expr e2) {
|
private predicate valueStep(Expr e1, Expr e2) {
|
||||||
@@ -669,10 +673,10 @@ module Make<
|
|||||||
* through a back edge.
|
* through a back edge.
|
||||||
*/
|
*/
|
||||||
private SsaDefinition getAnUltimateDefinition(SsaDefinition v, boolean fromBackEdge) {
|
private SsaDefinition getAnUltimateDefinition(SsaDefinition v, boolean fromBackEdge) {
|
||||||
result = v and not v instanceof SsaPhiNode and fromBackEdge = false
|
result = v and not v instanceof SsaPhiDefinition and fromBackEdge = false
|
||||||
or
|
or
|
||||||
exists(SsaDefinition inp, BasicBlock bb, boolean fbe |
|
exists(SsaDefinition inp, BasicBlock bb, boolean fbe |
|
||||||
v.(SsaPhiNode).hasInputFromBlock(inp, bb) and
|
v.(SsaPhiDefinition).hasInputFromBlock(inp, bb) and
|
||||||
result = getAnUltimateDefinition(inp, fbe) and
|
result = getAnUltimateDefinition(inp, fbe) and
|
||||||
(if v.getBasicBlock().dominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
|
(if v.getBasicBlock().dominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
|
||||||
)
|
)
|
||||||
@@ -683,9 +687,9 @@ module Make<
|
|||||||
*/
|
*/
|
||||||
private predicate hasPossibleUnknownValue(SsaDefinition v) {
|
private predicate hasPossibleUnknownValue(SsaDefinition v) {
|
||||||
exists(SsaDefinition def | def = getAnUltimateDefinition(v, _) |
|
exists(SsaDefinition def | def = getAnUltimateDefinition(v, _) |
|
||||||
not exists(def.(SsaWriteDefinition).getDefinition())
|
not exists(def.(SsaExplicitWrite).getValue())
|
||||||
or
|
or
|
||||||
exists(Expr e | e = possibleValue(def.(SsaWriteDefinition).getDefinition()) |
|
exists(Expr e | e = possibleValue(def.(SsaExplicitWrite).getValue()) |
|
||||||
not constantHasValue(e, _)
|
not constantHasValue(e, _)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -701,9 +705,9 @@ module Make<
|
|||||||
*/
|
*/
|
||||||
private predicate possibleValue(SsaDefinition v, boolean fromBackEdge, Expr e, GuardValue k) {
|
private predicate possibleValue(SsaDefinition v, boolean fromBackEdge, Expr e, GuardValue k) {
|
||||||
not hasPossibleUnknownValue(v) and
|
not hasPossibleUnknownValue(v) and
|
||||||
exists(SsaWriteDefinition def |
|
exists(SsaExplicitWrite def |
|
||||||
def = getAnUltimateDefinition(v, fromBackEdge) and
|
def = getAnUltimateDefinition(v, fromBackEdge) and
|
||||||
e = possibleValue(def.getDefinition()) and
|
e = possibleValue(def.getValue()) and
|
||||||
constantHasValue(e, k)
|
constantHasValue(e, k)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -711,7 +715,7 @@ module Make<
|
|||||||
/**
|
/**
|
||||||
* Holds if `e` equals `k` and may be assigned to `v` without going through
|
* Holds if `e` equals `k` and may be assigned to `v` without going through
|
||||||
* back edges, and all other possible ultimate definitions of `v` are different
|
* back edges, and all other possible ultimate definitions of `v` are different
|
||||||
* from `k`. The trivial case where `v` is an `SsaWriteDefinition` with `e` as
|
* from `k`. The trivial case where `v` is an `SsaExplicitWrite` with `e` as
|
||||||
* the only possible value is excluded.
|
* the only possible value is excluded.
|
||||||
*/
|
*/
|
||||||
private predicate uniqueValue(SsaDefinition v, Expr e, GuardValue k) {
|
private predicate uniqueValue(SsaDefinition v, Expr e, GuardValue k) {
|
||||||
@@ -727,14 +731,14 @@ module Make<
|
|||||||
* Holds if `phi` has exactly two inputs, `def1` and `e2`, and that `def1`
|
* Holds if `phi` has exactly two inputs, `def1` and `e2`, and that `def1`
|
||||||
* does not come from a back-edge into `phi`.
|
* does not come from a back-edge into `phi`.
|
||||||
*/
|
*/
|
||||||
private predicate phiWithTwoInputs(SsaPhiNode phi, SsaDefinition def1, Expr e2) {
|
private predicate phiWithTwoInputs(SsaPhiDefinition phi, SsaDefinition def1, Expr e2) {
|
||||||
exists(SsaWriteDefinition def2, BasicBlock bb1 |
|
exists(SsaExplicitWrite def2, BasicBlock bb1 |
|
||||||
2 = strictcount(SsaDefinition inp, BasicBlock bb | phi.hasInputFromBlock(inp, bb)) and
|
2 = strictcount(SsaDefinition inp, BasicBlock bb | phi.hasInputFromBlock(inp, bb)) and
|
||||||
phi.hasInputFromBlock(def1, bb1) and
|
phi.hasInputFromBlock(def1, bb1) and
|
||||||
phi.hasInputFromBlock(def2, _) and
|
phi.hasInputFromBlock(def2, _) and
|
||||||
def1 != def2 and
|
def1 != def2 and
|
||||||
not phi.getBasicBlock().dominates(bb1) and
|
not phi.getBasicBlock().dominates(bb1) and
|
||||||
def2.getDefinition() = e2
|
def2.getValue() = e2
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,8 +799,8 @@ module Make<
|
|||||||
baseSsaValueCheck(def, v, g, gv)
|
baseSsaValueCheck(def, v, g, gv)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SsaWriteDefinition def |
|
exists(SsaExplicitWrite def |
|
||||||
exprHasValue(def.getDefinition(), v) and
|
exprHasValue(def.getValue(), v) and
|
||||||
e = def.getARead()
|
e = def.getARead()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -841,7 +845,7 @@ module Make<
|
|||||||
bindingset[def1, v1]
|
bindingset[def1, v1]
|
||||||
pragma[inline_late]
|
pragma[inline_late]
|
||||||
private predicate impliesStepSsaGuard(SsaDefinition def1, GuardValue v1, Guard g2, GuardValue v2) {
|
private predicate impliesStepSsaGuard(SsaDefinition def1, GuardValue v1, Guard g2, GuardValue v2) {
|
||||||
def1.(SsaWriteDefinition).getDefinition() = g2 and
|
def1.(SsaExplicitWrite).getValue() = g2 and
|
||||||
v1 = v2 and
|
v1 = v2 and
|
||||||
not exprHasValue(g2, v2) // disregard trivial guard
|
not exprHasValue(g2, v2) // disregard trivial guard
|
||||||
or
|
or
|
||||||
@@ -1032,9 +1036,9 @@ module Make<
|
|||||||
private predicate validReturnInCustomGuard(
|
private predicate validReturnInCustomGuard(
|
||||||
ReturnExpr ret, ParameterPosition ppos, GuardValue retval, GuardValue val
|
ReturnExpr ret, ParameterPosition ppos, GuardValue retval, GuardValue val
|
||||||
) {
|
) {
|
||||||
exists(NonOverridableMethod m, SsaDefinition param |
|
exists(NonOverridableMethod m, SsaParameterInit param |
|
||||||
m.getAReturnExpr() = ret and
|
m.getAReturnExpr() = ret and
|
||||||
parameterDefinition(m.getParameter(ppos), param)
|
param.getParameter() = m.getParameter(ppos)
|
||||||
|
|
|
|
||||||
exists(Guard g0, GuardValue v0 |
|
exists(Guard g0, GuardValue v0 |
|
||||||
directlyControlsReturn(g0, v0, ret) and
|
directlyControlsReturn(g0, v0, ret) and
|
||||||
@@ -1071,8 +1075,8 @@ module Make<
|
|||||||
validReturnInCustomGuard(ret, ppos, retval, val)
|
validReturnInCustomGuard(ret, ppos, retval, val)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SsaDefinition param, Guard g0, GuardValue v0 |
|
exists(SsaParameterInit param, Guard g0, GuardValue v0 |
|
||||||
parameterDefinition(result.getParameter(ppos), param) and
|
param.getParameter() = result.getParameter(ppos) and
|
||||||
guardDirectlyControlsExit(g0, v0) and
|
guardDirectlyControlsExit(g0, v0) and
|
||||||
retval = TException(false) and
|
retval = TException(false) and
|
||||||
BranchImplies::ssaControls(param, val, g0, v0)
|
BranchImplies::ssaControls(param, val, g0, v0)
|
||||||
@@ -1141,9 +1145,9 @@ module Make<
|
|||||||
private predicate validReturnInValidationWrapper(
|
private predicate validReturnInValidationWrapper(
|
||||||
ReturnExpr ret, ParameterPosition ppos, GuardValue retval, State state
|
ReturnExpr ret, ParameterPosition ppos, GuardValue retval, State state
|
||||||
) {
|
) {
|
||||||
exists(NonOverridableMethod m, SsaDefinition param, Guard guard, GuardValue val |
|
exists(NonOverridableMethod m, SsaParameterInit param, Guard guard, GuardValue val |
|
||||||
m.getAReturnExpr() = ret and
|
m.getAReturnExpr() = ret and
|
||||||
parameterDefinition(m.getParameter(ppos), param) and
|
param.getParameter() = m.getParameter(ppos) and
|
||||||
guardChecksDef(guard, param, val, state)
|
guardChecksDef(guard, param, val, state)
|
||||||
|
|
|
|
||||||
guard.valueControls(ret.getBasicBlock(), val) and
|
guard.valueControls(ret.getBasicBlock(), val) and
|
||||||
@@ -1171,8 +1175,8 @@ module Make<
|
|||||||
validReturnInValidationWrapper(ret, ppos, retval, state)
|
validReturnInValidationWrapper(ret, ppos, retval, state)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SsaDefinition param, BasicBlock bb, Guard guard, GuardValue val |
|
exists(SsaParameterInit param, BasicBlock bb, Guard guard, GuardValue val |
|
||||||
parameterDefinition(result.getParameter(ppos), param) and
|
param.getParameter() = result.getParameter(ppos) and
|
||||||
guardChecksDef(guard, param, val, state) and
|
guardChecksDef(guard, param, val, state) and
|
||||||
guard.valueControls(bb, val) and
|
guard.valueControls(bb, val) and
|
||||||
normalExitBlock(bb) and
|
normalExitBlock(bb) and
|
||||||
|
|||||||
Reference in New Issue
Block a user