C++: Avoid `iDominates*` in Overflow.qll

The `iDominates` relation is directly on control-flow nodes, and its
transitive closure is far too large. It got compiled into a recursion
rather than `fastTC`, and I've observed that recursion to take about an
hour on a medium-size customer snapshot.

The fix is to check for dominance at the basic-block level.
This commit is contained in:
Jonas Jensen 2020-02-28 10:48:23 +01:00
Родитель 4ca57db553
Коммит dfe1a7e2f0
1 изменённых файлов: 17 добавлений и 4 удалений

Просмотреть файл

@ -13,19 +13,32 @@ predicate guardedAbs(Operation e, Expr use) {
)
}
pragma[inline]
private predicate stmtDominates(Stmt dominator, Stmt dominated) {
// In same block
exists(BasicBlock block, int dominatorIndex, int dominatedIndex |
block.getNode(dominatorIndex) = dominator and
block.getNode(dominatedIndex) = dominated and
dominatedIndex >= dominatorIndex
)
or
// In (possibly) different blocks
bbStrictlyDominates(dominator.getBasicBlock(), dominated.getBasicBlock())
}
/** is the size of this use guarded to be less than something? */
pragma[nomagic]
predicate guardedLesser(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard |
use = guard.getLesserOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
iDominates*(c.getThen(), e.getEnclosingStmt())
stmtDominates(c.getThen(), e.getEnclosingStmt())
)
or
exists(Loop c, RelationalOperation guard |
use = guard.getLesserOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
iDominates*(c.getStmt(), e.getEnclosingStmt())
stmtDominates(c.getStmt(), e.getEnclosingStmt())
)
or
exists(ConditionalExpr c, RelationalOperation guard |
@ -43,13 +56,13 @@ predicate guardedGreater(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard |
use = guard.getGreaterOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
iDominates*(c.getThen(), e.getEnclosingStmt())
stmtDominates(c.getThen(), e.getEnclosingStmt())
)
or
exists(Loop c, RelationalOperation guard |
use = guard.getGreaterOperand().getAChild*() and
guard = c.getControllingExpr().getAChild*() and
iDominates*(c.getStmt(), e.getEnclosingStmt())
stmtDominates(c.getStmt(), e.getEnclosingStmt())
)
or
exists(ConditionalExpr c, RelationalOperation guard |