Skip to content

Commit a617053

Browse files
committed
C#: Remove cases where suggestion would result in capturing expressions that access in/out or ref parameters.
1 parent e8440b7 commit a617053

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

‎csharp/ql/lib/Linq/Helpers.qll‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ class ForEachStmtEnumerable extends ForEachStmt {
116116
}
117117
}
118118

119+
bindingset[e]
120+
private predicate acceptableForLinqCapture(Expr e) {
121+
not exists(ParameterAccess pa, Parameter p | p = pa.getTarget() |
122+
pa = e.getAChildExpr*() and
123+
(p.isOutOrRef() or p.isIn() or p.isReadonlyRef())
124+
)
125+
}
126+
119127
private signature predicate linqCandidateSig(Stmt s, Expr e);
120128

121129
private module LinqFilterOpportunity<linqCandidateSig/2 linqCandidate> {
@@ -124,7 +132,8 @@ private module LinqFilterOpportunity<linqCandidateSig/2 linqCandidate> {
124132
// The linq candidate expression accesses the loop variable, and the
125133
// candidate doesn't access an in, out, or ref parameter.
126134
exists(Expr candidate | linqCandidate(s, candidate) |
127-
fes.getVariable().getAnAccess() = candidate.getAChildExpr*()
135+
fes.getVariable().getAnAccess() = candidate.getAChildExpr*() and
136+
acceptableForLinqCapture(candidate)
128137
)
129138
}
130139
}
@@ -137,7 +146,8 @@ private module LinqMapOpportunity<linqCandidateSig/2 linqCandidate> {
137146
exists(Expr candidate | linqCandidate(s, candidate) |
138147
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
139148
va = candidate.getAChildExpr*()
140-
)
149+
) and
150+
acceptableForLinqCapture(candidate)
141151
)
142152
}
143153
}

0 commit comments

Comments
 (0)