Skip to content

Commit 472ece4

Browse files
committed
Swift: Basic content flow through tuples.
1 parent a7ecdef commit 472ece4

File tree

4 files changed

+78
-8
lines changed

4 files changed

+78
-8
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ private module Cached {
177177
newtype TContentSet = TSingletonContent(Content c)
178178

179179
cached
180-
newtype TContent = TFieldContent(FieldDecl f)
180+
newtype TContent =
181+
TFieldContent(FieldDecl f) or
182+
TTupleContent(int index) { exists(any(TupleExpr tn).getElement(index)) }
181183
}
182184

183185
/**
@@ -505,6 +507,12 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
505507
c.isSingleton(any(Content::FieldContent ct | ct.getField() = ref.getMember()))
506508
)
507509
or
510+
exists(TupleExpr tuple, int pos |
511+
node1.asExpr() = tuple.getElement(pos) and
512+
node2.asExpr() = tuple and
513+
c.isSingleton(any(Content::TupleContent ct | ct.getIndex() = pos))
514+
)
515+
or
508516
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
509517
}
510518

@@ -517,6 +525,12 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
517525
node2.asExpr() = ref and
518526
c.isSingleton(any(Content::FieldContent ct | ct.getField() = ref.getMember()))
519527
)
528+
or
529+
exists(TupleElementExpr tuple |
530+
node1.asExpr() = tuple.getSubExpr() and
531+
node2.asExpr() = tuple and
532+
c.isSingleton(any(Content::TupleContent ct | ct.getIndex() = tuple.getIndex()))
533+
)
520534
}
521535

522536
/**

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,18 @@ module Content {
159159

160160
override string toString() { result = f.toString() }
161161
}
162+
163+
/** An element of a tuple at a specific index. */
164+
class TupleContent extends Content, TTupleContent {
165+
private int index;
166+
167+
TupleContent() { this = TTupleContent(index) }
168+
169+
/** Gets the index for this tuple element. */
170+
int getIndex() { result = index }
171+
172+
override string toString() { result = "Tuple element at index " + index.toString() }
173+
}
162174
}
163175

164176
/**

swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ edges
107107
| test.swift:266:15:266:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : |
108108
| test.swift:266:15:266:16 | ...? : | test.swift:266:15:266:25 | call to signum() : |
109109
| test.swift:266:15:266:25 | call to signum() : | test.swift:266:15:266:25 | OptionalEvaluationExpr |
110+
| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | test.swift:281:15:281:15 | t1 [Tuple element at index 1] : |
111+
| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | test.swift:287:15:287:15 | t1 [Tuple element at index 1] : |
112+
| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | test.swift:293:15:293:15 | t1 [Tuple element at index 1] : |
113+
| test.swift:277:18:277:25 | call to source() : | test.swift:277:14:277:26 | (...) [Tuple element at index 1] : |
114+
| test.swift:281:15:281:15 | t1 [Tuple element at index 1] : | test.swift:281:15:281:18 | .1 |
115+
| test.swift:287:15:287:15 | t1 [Tuple element at index 1] : | test.swift:287:15:287:18 | .1 |
116+
| test.swift:293:15:293:15 | t1 [Tuple element at index 1] : | test.swift:293:15:293:18 | .1 |
117+
| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | test.swift:302:15:302:15 | t1 [Tuple element at index 0] : |
118+
| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | test.swift:306:15:306:15 | t2 [Tuple element at index 0] : |
119+
| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | test.swift:303:15:303:15 | t1 [Tuple element at index 1] : |
120+
| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | test.swift:307:15:307:15 | t2 [Tuple element at index 1] : |
121+
| test.swift:297:18:297:25 | call to source() : | test.swift:297:14:297:45 | (...) [Tuple element at index 0] : |
122+
| test.swift:297:31:297:38 | call to source() : | test.swift:297:14:297:45 | (...) [Tuple element at index 1] : |
123+
| test.swift:302:15:302:15 | t1 [Tuple element at index 0] : | test.swift:302:15:302:18 | .0 |
124+
| test.swift:303:15:303:15 | t1 [Tuple element at index 1] : | test.swift:303:15:303:18 | .1 |
125+
| test.swift:306:15:306:15 | t2 [Tuple element at index 0] : | test.swift:306:15:306:18 | .0 |
126+
| test.swift:307:15:307:15 | t2 [Tuple element at index 1] : | test.swift:307:15:307:18 | .1 |
110127
nodes
111128
| file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : |
112129
| file://:0:0:0:0 | .x : | semmle.label | .x : |
@@ -227,6 +244,26 @@ nodes
227244
| test.swift:266:15:266:16 | ...? : | semmle.label | ...? : |
228245
| test.swift:266:15:266:25 | OptionalEvaluationExpr | semmle.label | OptionalEvaluationExpr |
229246
| test.swift:266:15:266:25 | call to signum() : | semmle.label | call to signum() : |
247+
| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : |
248+
| test.swift:277:18:277:25 | call to source() : | semmle.label | call to source() : |
249+
| test.swift:281:15:281:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : |
250+
| test.swift:281:15:281:18 | .1 | semmle.label | .1 |
251+
| test.swift:287:15:287:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : |
252+
| test.swift:287:15:287:18 | .1 | semmle.label | .1 |
253+
| test.swift:293:15:293:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : |
254+
| test.swift:293:15:293:18 | .1 | semmle.label | .1 |
255+
| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | semmle.label | (...) [Tuple element at index 0] : |
256+
| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : |
257+
| test.swift:297:18:297:25 | call to source() : | semmle.label | call to source() : |
258+
| test.swift:297:31:297:38 | call to source() : | semmle.label | call to source() : |
259+
| test.swift:302:15:302:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : |
260+
| test.swift:302:15:302:18 | .0 | semmle.label | .0 |
261+
| test.swift:303:15:303:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : |
262+
| test.swift:303:15:303:18 | .1 | semmle.label | .1 |
263+
| test.swift:306:15:306:15 | t2 [Tuple element at index 0] : | semmle.label | t2 [Tuple element at index 0] : |
264+
| test.swift:306:15:306:18 | .0 | semmle.label | .0 |
265+
| test.swift:307:15:307:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : |
266+
| test.swift:307:15:307:18 | .1 | semmle.label | .1 |
230267
subpaths
231268
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:31:75:32 | [post] &... : |
232269
| test.swift:114:19:114:19 | arg : | test.swift:109:9:109:14 | arg : | test.swift:110:12:110:12 | arg : | test.swift:114:12:114:22 | call to ... : |
@@ -287,3 +324,10 @@ subpaths
287324
| test.swift:264:15:264:16 | ...! | test.swift:259:12:259:19 | call to source() : | test.swift:264:15:264:16 | ...! | result |
288325
| test.swift:265:15:265:31 | call to signum() | test.swift:265:15:265:22 | call to source() : | test.swift:265:15:265:31 | call to signum() | result |
289326
| test.swift:266:15:266:25 | OptionalEvaluationExpr | test.swift:259:12:259:19 | call to source() : | test.swift:266:15:266:25 | OptionalEvaluationExpr | result |
327+
| test.swift:281:15:281:18 | .1 | test.swift:277:18:277:25 | call to source() : | test.swift:281:15:281:18 | .1 | result |
328+
| test.swift:287:15:287:18 | .1 | test.swift:277:18:277:25 | call to source() : | test.swift:287:15:287:18 | .1 | result |
329+
| test.swift:293:15:293:18 | .1 | test.swift:277:18:277:25 | call to source() : | test.swift:293:15:293:18 | .1 | result |
330+
| test.swift:302:15:302:18 | .0 | test.swift:297:18:297:25 | call to source() : | test.swift:302:15:302:18 | .0 | result |
331+
| test.swift:303:15:303:18 | .1 | test.swift:297:31:297:38 | call to source() : | test.swift:303:15:303:18 | .1 | result |
332+
| test.swift:306:15:306:18 | .0 | test.swift:297:18:297:25 | call to source() : | test.swift:306:15:306:18 | .0 | result |
333+
| test.swift:307:15:307:18 | .1 | test.swift:297:31:297:38 | call to source() : | test.swift:307:15:307:18 | .1 | result |

swift/ql/test/library-tests/dataflow/dataflow/test.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,19 +278,19 @@ func testTuples() {
278278

279279
sink(arg: t1)
280280
sink(arg: t1.0)
281-
sink(arg: t1.1) // $ MISSING: flow=277
281+
sink(arg: t1.1) // $ flow=277
282282

283283
t1.1 = 2
284284

285285
sink(arg: t1)
286286
sink(arg: t1.0)
287-
sink(arg: t1.1)
287+
sink(arg: t1.1) // $ SPURIOUS: flow=277
288288

289289
t1.0 = source()
290290

291291
sink(arg: t1)
292292
sink(arg: t1.0) // $ MISSING: flow=289
293-
sink(arg: t1.1)
293+
sink(arg: t1.1) // $ SPURIOUS: flow=277
294294
}
295295

296296
func testTuples2() {
@@ -299,12 +299,12 @@ func testTuples2() {
299299
let (a, b, c) = t1
300300

301301
sink(arg: t1)
302-
sink(arg: t1.x) // $ MISSING: flow=297
303-
sink(arg: t1.y) // $ MISSING: flow=297
302+
sink(arg: t1.x) // $ flow=297
303+
sink(arg: t1.y) // $ flow=297
304304
sink(arg: t1.z)
305305
sink(arg: t2)
306-
sink(arg: t2.x) // $ MISSING: flow=297
307-
sink(arg: t2.y) // $ MISSING: flow=297
306+
sink(arg: t2.x) // $ flow=297
307+
sink(arg: t2.y) // $ flow=297
308308
sink(arg: t2.z)
309309
sink(arg: a) // $ MISSING: flow=297
310310
sink(arg: b) // $ MISSING: flow=297

0 commit comments

Comments
 (0)