Further optimise guardingFunction: remove redundant condition, and order guard -> guardFunction case to work backwards from interesting return sites, allowing us to go backwards not forwards through BasicBlock::dominates

This commit is contained in:
Chris Smowton
2024-10-08 15:34:12 +01:00
parent d401891d30
commit 629a7a601d

View File

@@ -341,6 +341,21 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
localFlow(pragma[only_bind_out](outp.getNode(c)), resNode)
}
private predicate onlyPossibleReturnSatisfyingProperty(
FuncDecl fd, FunctionOutput outp, Node ret, DataFlow::Property p
) {
exists(boolean b |
onlyPossibleReturnOfBool(fd, outp, ret, b) and
p.isBoolean(b)
)
or
onlyPossibleReturnOfNonNil(fd, outp, ret) and
p.isNonNil()
or
onlyPossibleReturnOfNil(fd, outp, ret) and
p.isNil()
}
/**
* Holds if whenever `p` holds of output `outp` of function `f`, this node
* is known to validate the input `inp` of `f`.
@@ -356,23 +371,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
exists(FuncDecl fd, Node arg, Node ret |
fd.getFunction() = f and
localFlow(inp.getExitNode(fd), pragma[only_bind_out](arg)) and
ret = outp.getEntryNode(fd) and
(
// Case: a function like "if someBarrierGuard(arg) { return true } else { return false }"
exists(ControlFlow::ConditionGuardNode guard |
guards(g, guard, arg) and
guard.dominates(ret.getBasicBlock())
guards(g, pragma[only_bind_out](guard), arg) and
guard.dominates(pragma[only_bind_out](ret).getBasicBlock())
|
exists(boolean b |
onlyPossibleReturnOfBool(fd, outp, ret, b) and
p.isBoolean(b)
)
or
onlyPossibleReturnOfNonNil(fd, outp, ret) and
p.isNonNil()
or
onlyPossibleReturnOfNil(fd, outp, ret) and
p.isNil()
onlyPossibleReturnSatisfyingProperty(fd, outp, ret, p)
)
or
// Case: a function like "return someBarrierGuard(arg)"