Skip to content

Commit 6d55044

Browse files
committed
Swift: Only create a 'ThrowCompletion' for functions that actually can throw.
1 parent 2dcd7e1 commit 6d55044

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ abstract class Completion extends TCompletion {
7070
predicate isValidFor(ControlFlowElement n) {
7171
this.isValidForSpecific(n)
7272
or
73-
mayHaveThrowCompletion(n.asAstNode(), this)
73+
mayHaveThrowCompletion(n, this)
7474
or
7575
not any(Completion c).isValidForSpecific(n) and
7676
this = TSimpleCompletion()
@@ -328,10 +328,16 @@ private predicate isMatchingConstant(CaseLabelItem cli, boolean value) {
328328

329329
private predicate mustHaveThrowCompletion(ThrowStmt throw, ThrowCompletion c) { any() }
330330

331-
private predicate mayHaveThrowCompletion(ApplyExpr n, ThrowCompletion c) {
332-
// TODO: We should really just use the function type here, I think (and then check
333-
// if the type has a `throws`).
334-
exists(n.getStaticTarget())
331+
private predicate isThrowingType(AnyFunctionType type) { type.isThrowing() }
332+
333+
private predicate mayHaveThrowCompletion(ControlFlowElement n, ThrowCompletion c) {
334+
// An AST expression that may throw.
335+
isThrowingType(n.asAstNode().(ApplyExpr).getFunction().getType())
336+
or
337+
// Getters are the only accessor declarators that may throw.
338+
exists(AccessorDecl accessor | isThrowingType(accessor.getInterfaceType()) |
339+
isPropertyGetterElement(n, accessor, _)
340+
)
335341
}
336342

337343
/**

0 commit comments

Comments
 (0)