Skip to content

Commit 32442a3

Browse files
authored
Merge pull request #11270 from geoffw0/optionals2
Swift: Dataflow through ?? and ? :
2 parents 184c903 + c6835cd commit 32442a3

File tree

9 files changed

+316
-126
lines changed

9 files changed

+316
-126
lines changed

swift/ql/.generated.list

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ ql/lib/codeql/swift/elements/expr/OverloadedDeclRefExprConstructor.qll 2cf79b483
184184
ql/lib/codeql/swift/elements/expr/ParenExprConstructor.qll 6baaa592db57870f5ecd9be632bd3f653c44d72581efd41e8a837916e1590f9e 6f28988d04b2cb69ddcb63fba9ae3166b527803a61c250f97e48ff39a28379f6
185185
ql/lib/codeql/swift/elements/expr/PointerToPointerExpr.qll 921645a373443d050dbc29b9f6bc4a734163c75aeffce453a4f8334b34077d30 54089de77845f6b0e623c537bc25a010ecf1b5c7630b1b4060d2b378abc07f4e
186186
ql/lib/codeql/swift/elements/expr/PointerToPointerExprConstructor.qll 95cc8003b9a3b2101afb8f110ec4cbd29e380fc048ee080f5047bcf0e14a06c7 114d487a1bb2cd33b27a9c3a47ad1d7254766e169512642f8b09b9c32cf3dc86
187-
ql/lib/codeql/swift/elements/expr/PostfixUnaryExpr.qll a67abdf379f04f1aeee0795cd3ebeb28ed8dfe0efad15b128d44cc9e30b32cbd cbb2b2d54c8e316dc71388ea4ff6bb5d0a6204b4e9d9ce2888e1877a54e85e8f
188187
ql/lib/codeql/swift/elements/expr/PostfixUnaryExprConstructor.qll c26326e2703b9a8b077ea9f132ae86a76b4010a108b8dcde29864f4206096231 70e45fbe365b63226d0132158cdd453e2e00d740a31c1fb0f7bfb3b2dedfd928
189188
ql/lib/codeql/swift/elements/expr/PrefixUnaryExprConstructor.qll 6d4c915baf460691cc22681154b1129852c26f1bd9fe3e27b4e162f819d934f5 7971698433bc03dbff2fec34426a96a969fab1a5a575aaf91f10044819e16f6d
190189
ql/lib/codeql/swift/elements/expr/PropertyWrapperValuePlaceholderExpr.qll 35a61a7f68e71165690127b445fff39780028cb6be5e7b5eadaafa8aeb6b2321 f9e32f65e6d453d3fa857a4d3ca19700be1f8ea2f3d13534656bc21a2fc5f0b0

swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,29 @@ private module Cached {
148148
// flow through `!`
149149
nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr()
150150
or
151-
// flow through `?`
151+
// flow through `?` and `?.`
152152
nodeFrom.asExpr() = nodeTo.asExpr().(BindOptionalExpr).getSubExpr()
153153
or
154154
nodeFrom.asExpr() = nodeTo.asExpr().(OptionalEvaluationExpr).getSubExpr()
155155
or
156+
// flow through nil-coalescing operator `??`
157+
exists(BinaryExpr nco |
158+
nco.getOperator().(FreeFunctionDecl).getName() = "??(_:_:)" and
159+
nodeTo.asExpr() = nco
160+
|
161+
// value argument
162+
nodeFrom.asExpr() = nco.getAnOperand()
163+
or
164+
// unpack closure (the second argument is an `AutoClosureExpr` argument)
165+
nodeFrom.asExpr() = nco.getAnOperand().(AutoClosureExpr).getExpr()
166+
)
167+
or
168+
// flow through ternary operator `? :`
169+
exists(IfExpr ie |
170+
nodeTo.asExpr() = ie and
171+
nodeFrom.asExpr() = ie.getBranch(_)
172+
)
173+
or
156174
// flow through a flow summary (extension of `SummaryModelCsv`)
157175
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
158176
}
Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
private import codeql.swift.generated.expr.AutoClosureExpr
22
private import codeql.swift.elements.stmt.ReturnStmt
3+
private import codeql.swift.elements.expr.Expr
34

5+
/**
6+
* A Swift autoclosure expression, that is, a closure automatically generated
7+
* around an argument when the parameter has the `@autoclosure` attribute. For
8+
* example, there is an `AutoClosureExpr` around the value `0` in:
9+
* ```
10+
* func myFunction(_ expr: @autoclosure () -> Int) {
11+
* ...
12+
* }
13+
*
14+
* myFunction(0)
15+
* ```
16+
*/
417
class AutoClosureExpr extends Generated::AutoClosureExpr {
5-
/** Gets the implicit return statement generated by this autoclosure expression. */
18+
/**
19+
* Gets the implicit return statement generated by this autoclosure expression.
20+
*/
621
ReturnStmt getReturn() { result = unique( | | this.getBody().getAnElement()) }
722

23+
/**
24+
* Gets the expression returned by this autoclosure expression.
25+
*/
26+
Expr getExpr() { result = this.getReturn().getResult() }
27+
828
override string toString() { result = this.getBody().toString() }
929
}

swift/ql/lib/codeql/swift/elements/expr/BinaryExpr.qll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
private import codeql.swift.generated.expr.BinaryExpr
22
private import codeql.swift.elements.expr.Expr
3+
private import codeql.swift.elements.decl.AbstractFunctionDecl
34

5+
/**
6+
* A Swift binary expression, that is, an expression that appears between its
7+
* two operands. For example:
8+
* ```
9+
* x + y
10+
* ```
11+
*/
412
class BinaryExpr extends Generated::BinaryExpr {
13+
/**
14+
* Gets the left operand (left expression) of this binary expression.
15+
*/
516
Expr getLeftOperand() { result = this.getArgument(0).getExpr() }
617

18+
/**
19+
* Gets the right operand (right expression) of this binary expression.
20+
*/
721
Expr getRightOperand() { result = this.getArgument(1).getExpr() }
822

23+
/**
24+
* Gets the operator of this binary expression (the function that is called).
25+
*/
26+
AbstractFunctionDecl getOperator() { result = this.getStaticTarget() }
27+
28+
/**
29+
* Gets an operand of this binary expression (left or right).
30+
*/
931
Expr getAnOperand() { result = [this.getLeftOperand(), this.getRightOperand()] }
1032

1133
override string toString() { result = "... " + this.getFunction().toString() + " ..." }
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.PostfixUnaryExpr
2+
private import codeql.swift.elements.expr.Expr
3+
private import codeql.swift.elements.decl.AbstractFunctionDecl
34

4-
class PostfixUnaryExpr extends Generated::PostfixUnaryExpr { }
5+
/**
6+
* A Swift postfix unary expression, that is, a unary expression that appears
7+
* after its operand. For example:
8+
* ```
9+
* x!
10+
* ```
11+
*/
12+
class PostfixUnaryExpr extends Generated::PostfixUnaryExpr {
13+
/**
14+
* Gets the operand (expression) of this postfix unary expression.
15+
*/
16+
Expr getOperand() { result = this.getAnArgument().getExpr() }
17+
18+
/**
19+
* Gets the operator of this postfix unary expression (the function that is called).
20+
*/
21+
AbstractFunctionDecl getOperator() { result = this.getStaticTarget() }
22+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
private import codeql.swift.generated.expr.PrefixUnaryExpr
22
private import codeql.swift.elements.expr.Expr
3+
private import codeql.swift.elements.decl.AbstractFunctionDecl
34

5+
/**
6+
* A Swift prefix unary expression, that is, a unary expression that appears
7+
* before its operand. For example:
8+
* ```
9+
* -x
10+
* ```
11+
*/
412
class PrefixUnaryExpr extends Generated::PrefixUnaryExpr {
13+
/**
14+
* Gets the operand (expression) of this prefix unary expression.
15+
*/
516
Expr getOperand() { result = this.getAnArgument().getExpr() }
17+
18+
/**
19+
* Gets the operator of this prefix unary expression (the function that is called).
20+
*/
21+
AbstractFunctionDecl getOperator() { result = this.getStaticTarget() }
622
}

0 commit comments

Comments
 (0)