Skip to content

Commit 8da4e2d

Browse files
committed
Rust: Fixes to flow through captured variables
1 parent 2929376 commit 8da4e2d

6 files changed

Lines changed: 78 additions & 89 deletions

File tree

‎rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll‎

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ module VariableCapture {
10701070
final class CapturedParameter extends CapturedVariable {
10711071
ParamBase p;
10721072

1073-
CapturedParameter() { p = this.getParameter() }
1073+
CapturedParameter() { this.isParameter(p) }
10741074

10751075
SourceParameterNode getParameterNode() { result.getParameter() = p }
10761076
}
@@ -1080,33 +1080,15 @@ module VariableCapture {
10801080
}
10811081

10821082
class VariableWrite extends Expr {
1083-
Expr source;
10841083
CapturedVariable v;
10851084

10861085
VariableWrite() {
1087-
exists(AssignmentExpr assign, Variable::VariableWriteAccess write |
1088-
this = assign and
1089-
v = write.getVariable() and
1090-
assign.getLhs() = write and
1091-
assign.getRhs() = source
1092-
)
1093-
or
1094-
this =
1095-
any(LetStmt ls |
1096-
v.getPat() = ls.getPat() and
1097-
ls.getInitializer() = source
1098-
)
1086+
this = v.getPat()
10991087
or
1100-
this =
1101-
any(LetExpr le |
1102-
v.getPat() = le.getPat() and
1103-
le.getScrutinee() = source
1104-
)
1088+
v = this.(Variable::VariableWriteAccess).getVariable()
11051089
}
11061090

11071091
CapturedVariable getVariable() { result = v }
1108-
1109-
Expr getSource() { result = source }
11101092
}
11111093

11121094
class VariableRead extends Expr {
@@ -1145,7 +1127,7 @@ module VariableCapture {
11451127
or
11461128
result.(Flow::ExprNode).getExpr() = n.asExpr()
11471129
or
1148-
result.(Flow::VariableWriteSourceNode).getVariableWrite().getSource() = n.asExpr()
1130+
result.(Flow::VariableWriteSourceNode).getVariableWrite() = n.getAstNode()
11491131
or
11501132
result.(Flow::ExprPostUpdateNode).getExpr() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
11511133
or

‎rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,12 @@ module Impl {
310310
/** Holds if this variable is captured. */
311311
predicate isCaptured() { this.getAnAccess().isCapture() }
312312

313-
/** Gets the parameter that introduces this variable, if any. */
313+
/**
314+
* Gets the parameter that introduces this variable, if any.
315+
*
316+
* Note that this variable need not be a direct parameter; it could
317+
* also be introduced through a destructuring pattern.
318+
*/
314319
cached
315320
ParamBase getParameter() {
316321
CachedStage::ref() and
@@ -319,6 +324,14 @@ module Impl {
319324
result.(Param).getPat() = getAPatAncestor*(this.getPat())
320325
}
321326

327+
/** Holds if this variable corresponds directly to the parameter `p`. */
328+
predicate isParameter(ParamBase p) {
329+
CachedStage::ref() and
330+
p = this.getSelfParam()
331+
or
332+
p.(Param).getPat() = this.getPat()
333+
}
334+
322335
/** Holds if this variable is mutable. */
323336
predicate isMutable() { this.getPat().isMut() or this.getSelfParam().isMut() }
324337

‎rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2348,7 +2348,7 @@ private module Input3 implements InputSig3 {
23482348

23492349
AstNode getDefiningNode() {
23502350
result = this.asLocalVariable().getPat().getName() or
2351-
result = this.asLocalVariable().getParameter().(SelfParam) or
2351+
this.asLocalVariable().isParameter(result.(SelfParam)) or
23522352
result = this.asConst().getName() or
23532353
result = this.asStatic().getName()
23542354
}

‎rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ edges
1313
| main.rs:29:13:29:22 | f(...) | main.rs:29:9:29:9 | b | provenance | |
1414
| main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | provenance | |
1515
| main.rs:29:21:29:21 | a | main.rs:29:13:29:22 | f(...) | provenance | |
16-
| main.rs:37:16:37:25 | source(...) | main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | provenance | |
16+
| main.rs:37:9:37:12 | capt | main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | provenance | |
17+
| main.rs:37:16:37:25 | source(...) | main.rs:37:9:37:12 | capt | provenance | |
1718
| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | main.rs:40:10:40:13 | capt | provenance | |
1819
| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | main.rs:44:5:44:5 | g [captured capt] | provenance | |
1920
| main.rs:44:5:44:5 | g [captured capt] | main.rs:42:14:42:17 | capt | provenance | |
@@ -55,22 +56,26 @@ edges
5556
| main.rs:100:13:100:22 | source(...) | main.rs:100:9:100:9 | b | provenance | |
5657
| main.rs:101:17:101:17 | ... | main.rs:101:25:101:25 | x | provenance | |
5758
| main.rs:101:29:101:29 | b | main.rs:93:33:93:38 | ...: i64 | provenance | |
58-
| main.rs:109:13:109:22 | source(...) | main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | provenance | |
59-
| main.rs:109:13:109:22 | source(...) | main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | provenance | |
60-
| main.rs:109:13:109:22 | source(...) | main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | provenance | |
61-
| main.rs:109:13:109:22 | source(...) | main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | provenance | |
59+
| main.rs:109:9:109:9 | a | main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | provenance | |
60+
| main.rs:109:9:109:9 | a | main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | provenance | |
61+
| main.rs:109:9:109:9 | a | main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | provenance | |
62+
| main.rs:109:9:109:9 | a | main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | provenance | |
63+
| main.rs:109:13:109:22 | source(...) | main.rs:109:9:109:9 | a | provenance | |
6264
| main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | main.rs:110:35:110:35 | a | provenance | heuristic-callback |
6365
| main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | main.rs:111:35:111:35 | a | provenance | heuristic-callback |
6466
| main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | main.rs:112:35:112:35 | a | provenance | heuristic-callback |
6567
| main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | main.rs:113:35:113:35 | a | provenance | heuristic-callback |
6668
| main.rs:120:30:120:40 | source(...) | main.rs:121:14:121:25 | await future | provenance | |
67-
| main.rs:125:20:125:30 | source(...) | main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | provenance | |
69+
| main.rs:125:13:125:16 | data | main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | provenance | |
70+
| main.rs:125:20:125:30 | source(...) | main.rs:125:13:125:16 | data | provenance | |
6871
| main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | main.rs:127:18:127:21 | data | provenance | |
69-
| main.rs:133:20:133:30 | source(...) | main.rs:135:14:135:19 | future [captured data] | provenance | |
72+
| main.rs:133:13:133:16 | data | main.rs:135:14:135:19 | future [captured data] | provenance | |
73+
| main.rs:133:20:133:30 | source(...) | main.rs:133:13:133:16 | data | provenance | |
7074
| main.rs:135:14:135:19 | future [captured data] | main.rs:134:30:134:33 | data | provenance | |
7175
| main.rs:135:14:135:19 | future [captured data] | main.rs:135:14:135:25 | await future | provenance | |
7276
| main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | main.rs:145:14:145:21 | captured | provenance | |
73-
| main.rs:142:24:142:34 | source(...) | main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | provenance | |
77+
| main.rs:142:13:142:20 | captured | main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | provenance | |
78+
| main.rs:142:24:142:34 | source(...) | main.rs:142:13:142:20 | captured | provenance | |
7479
nodes
7580
| main.rs:10:20:10:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} |
7681
| main.rs:10:30:10:39 | source(...) | semmle.label | source(...) |
@@ -88,6 +93,7 @@ nodes
8893
| main.rs:29:13:29:22 | f(...) | semmle.label | f(...) |
8994
| main.rs:29:21:29:21 | a | semmle.label | a |
9095
| main.rs:30:10:30:10 | b | semmle.label | b |
96+
| main.rs:37:9:37:12 | capt | semmle.label | capt |
9197
| main.rs:37:16:37:25 | source(...) | semmle.label | source(...) |
9298
| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | semmle.label | [post] f : ... => .. [captured capt] |
9399
| main.rs:40:10:40:13 | capt | semmle.label | capt |
@@ -137,6 +143,7 @@ nodes
137143
| main.rs:101:17:101:17 | ... | semmle.label | ... |
138144
| main.rs:101:25:101:25 | x | semmle.label | x |
139145
| main.rs:101:29:101:29 | b | semmle.label | b |
146+
| main.rs:109:9:109:9 | a | semmle.label | a |
140147
| main.rs:109:13:109:22 | source(...) | semmle.label | source(...) |
141148
| main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] |
142149
| main.rs:110:35:110:35 | a | semmle.label | a |
@@ -148,14 +155,17 @@ nodes
148155
| main.rs:113:35:113:35 | a | semmle.label | a |
149156
| main.rs:120:30:120:40 | source(...) | semmle.label | source(...) |
150157
| main.rs:121:14:121:25 | await future | semmle.label | await future |
158+
| main.rs:125:13:125:16 | data | semmle.label | data |
151159
| main.rs:125:20:125:30 | source(...) | semmle.label | source(...) |
152160
| main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | semmle.label | { ... } : ... => .. [captured data] |
153161
| main.rs:127:18:127:21 | data | semmle.label | data |
162+
| main.rs:133:13:133:16 | data | semmle.label | data |
154163
| main.rs:133:20:133:30 | source(...) | semmle.label | source(...) |
155164
| main.rs:134:30:134:33 | data | semmle.label | data |
156165
| main.rs:135:14:135:19 | future [captured data] | semmle.label | future [captured data] |
157166
| main.rs:135:14:135:25 | await future | semmle.label | await future |
158167
| main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | semmle.label | [post] { ... } : ... => .. [captured captured] |
168+
| main.rs:142:13:142:20 | captured | semmle.label | captured |
159169
| main.rs:142:24:142:34 | source(...) | semmle.label | source(...) |
160170
| main.rs:145:14:145:21 | captured | semmle.label | captured |
161171
subpaths

0 commit comments

Comments
 (0)