Skip to content

Commit 16c5b57

Browse files
committed
Shared: Extend the shared Guards library with support for exception branch points.
1 parent 14b87f9 commit 16c5b57

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

shared/controlflow/codeql/controlflow/Guards.qll

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ signature module InputSig<LocationSig Location> {
3737
string toString();
3838
}
3939

40+
class ExceptionSuccessor extends SuccessorType;
41+
4042
class ConditionalSuccessor extends SuccessorType {
4143
/** Gets the Boolean value of this successor. */
4244
boolean getValue();
@@ -187,7 +189,8 @@ module Make<LocationSig Location, InputSig<Location> Input> {
187189

188190
private newtype TGuardValue =
189191
TValue(TAbstractSingleValue val, Boolean isVal) or
190-
TCaseMatch(Case c, Boolean match)
192+
TCaseMatch(Case c, Boolean match) or
193+
TException(Boolean throws)
191194

192195
private class AbstractSingleValue extends TAbstractSingleValue {
193196
/** Gets a textual representation of this value. */
@@ -221,6 +224,11 @@ module Make<LocationSig Location, InputSig<Location> Input> {
221224
this = TCaseMatch(c, match) and
222225
result = TCaseMatch(c, match.booleanNot())
223226
)
227+
or
228+
exists(boolean throws |
229+
this = TException(throws) and
230+
result = TException(throws.booleanNot())
231+
)
224232
}
225233

226234
/** Holds if this value represents `null`. */
@@ -235,6 +243,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
235243
/** Gets the constant that this value represents, if any. */
236244
ConstantValue asConstantValue() { this = TValue(TValueConstant(result), true) }
237245

246+
/** Holds if this value represents throwing an exception. */
247+
predicate isThrowsException() { this = TException(true) }
248+
238249
/** Gets a textual representation of this value. */
239250
string toString() {
240251
result = this.asBooleanValue().toString()
@@ -257,6 +268,12 @@ module Make<LocationSig Location, InputSig<Location> Input> {
257268
match = false and result = "non-match " + s
258269
)
259270
)
271+
or
272+
exists(boolean throws | this = TException(throws) |
273+
throws = true and result = "exception"
274+
or
275+
throws = false and result = "no exception"
276+
)
260277
}
261278
}
262279

@@ -288,6 +305,15 @@ module Make<LocationSig Location, InputSig<Location> Input> {
288305
e instanceof NonNullExpr and v = TValue(TValueNull(), false)
289306
}
290307

308+
private predicate exceptionBranchPoint(BasicBlock bb1, BasicBlock normalSucc, BasicBlock excSucc) {
309+
exists(SuccessorType norm, ExceptionSuccessor exc |
310+
bb1.getASuccessor(norm) = normalSucc and
311+
bb1.getASuccessor(exc) = excSucc and
312+
normalSucc != excSucc and
313+
not norm instanceof ExceptionSuccessor
314+
)
315+
}
316+
291317
private predicate branchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue v) {
292318
exists(ConditionalSuccessor s |
293319
bb1.getASuccessor(s) = bb2 and
@@ -307,6 +333,10 @@ module Make<LocationSig Location, InputSig<Location> Input> {
307333
v = TCaseMatch(c, false) and
308334
c.nonMatchEdge(bb1, bb2)
309335
)
336+
or
337+
exceptionBranchPoint(bb1, bb2, _) and v = TException(false)
338+
or
339+
exceptionBranchPoint(bb1, _, bb2) and v = TException(true)
310340
}
311341

312342
pragma[nomagic]
@@ -399,7 +429,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
399429
bindingset[g1, v1]
400430
pragma[inline_late]
401431
private predicate unboundBaseImpliesStep(PreGuard g1, GuardValue v1, PreGuard g2, GuardValue v2) {
402-
g1.(IdExpr).getEqualChildExpr() = g2 and v1 = v2
432+
g1.(IdExpr).getEqualChildExpr() = g2 and v1 = v2 and not v1 instanceof TException
403433
or
404434
exists(ConditionalExpr cond, boolean branch, Expr e, GuardValue ev |
405435
cond = g1 and

0 commit comments

Comments
 (0)