Guards: Align the SSA signature with the one from shared SSA.

This commit is contained in:
Anders Schack-Mulligen
2025-10-23 10:16:38 +02:00
parent f6cddc9db7
commit f257c7a570
4 changed files with 56 additions and 50 deletions

View File

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

View File

@@ -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) {

View File

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

View File

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