Fix guard basic block for switch cases

This commit is contained in:
Chris Smowton
2023-11-16 16:49:19 +00:00
parent 6583c72c5d
commit c1814408f0
2 changed files with 33 additions and 3 deletions

View File

@@ -450,6 +450,20 @@ class SwitchCase extends Stmt, @case {
result = this.getSwitch().getExpr() or result = this.getSwitchExpr().getExpr()
}
/**
* Gets the `i`th case in this case's switch block.
*/
SwitchCase getSiblingCase(int i) {
result = this.getSwitch().getCase(i) or result = this.getSwitchExpr().getCase(i)
}
/**
* Gets this case's ordinal in its switch block.
*/
int getCaseIndex() {
this = this.getSwitch().getCase(result) or this = this.getSwitchExpr().getCase(result)
}
/**
* Holds if this `case` is a switch labeled rule of the form `... -> ...`.
*/

View File

@@ -103,11 +103,27 @@ class Guard extends ExprParent {
}
/**
* Gets the basic block containing this guard or the basic block containing
* the switch expression if the guard is a switch case.
* Gets the basic block containing this guard or the basic block that tests the
* applicability of this switch case -- for a pattern case this is the case statement
* itself; for a non-pattern case this is the most recent pattern case or the top of
* the switch block if there is none.
*/
BasicBlock getBasicBlock() {
result = this.(Expr).getBasicBlock() or
// Not a switch case
result = this.(Expr).getBasicBlock()
or
// Return the closest pattern case statement before this one, including this one.
result =
max(int i, PatternCase c |
c = this.(SwitchCase).getSiblingCase(i) and i <= this.(SwitchCase).getCaseIndex()
|
c order by i
).getBasicBlock()
or
// Not a pattern case and no preceding pattern case -- return the top of the switch block.
not exists(PatternCase c, int i |
c = this.(SwitchCase).getSiblingCase(i) and i <= this.(SwitchCase).getCaseIndex()
) and
result = this.(SwitchCase).getSelectorExpr().getBasicBlock()
}