Skip to content

Commit 53ebe23

Browse files
author
AndreiDiaconu1
committed
Better retrieval for the GetEnumerator call
1 parent 320cd6b commit 53ebe23

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/desugar/Foreach.qll

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,16 +206,27 @@ private class TranslatedForeachGetEnumerator extends TranslatedCompilerGenerated
206206
result = getInstructionFunction(CallTargetTag()).getReturnType()
207207
}
208208

209+
private Callable getEnumeratorCallable() {
210+
if exists(generatedBy.getIterableExpr().getType().(ValueOrRefType).getAMember("GetEnumerator"))
211+
then
212+
result = generatedBy.getIterableExpr().getType().(ValueOrRefType).getAMember("GetEnumerator")
213+
else
214+
exists(Interface inter |
215+
inter = generatedBy
216+
.getIterableExpr()
217+
.getType()
218+
.(ValueOrRefType)
219+
// There could be some abstract base types until we reach `IEnumerable` (eg. `Array`)
220+
.getABaseType*()
221+
.getABaseInterface() and
222+
inter.getName() = "IEnumerable" and
223+
result = inter.getAMember("GetEnumerator")
224+
)
225+
}
226+
209227
override Callable getInstructionFunction(InstructionTag tag) {
210228
tag = CallTargetTag() and
211-
result.getName() = "GetEnumerator" and
212-
// TODO: For now ignore the possibility that the
213-
// foreach variable can have a generic type.
214-
// The type of the callable will need to be fabricated,
215-
// since we might not find the correct callable in the DB.
216-
// Probably will have change the way the immediate
217-
// operand of `FunctionAddress` is calculated.
218-
result.getReturnType().getName() = "IEnumerator"
229+
result = getEnumeratorCallable()
219230
}
220231

221232
override TranslatedExpr getArgument(int id) { none() }

csharp/ql/src/semmle/code/csharp/ir/internal/IRCSharpLanguage.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ predicate hasPositionalArgIndex(int argIndex) {
7777
// correct number of parameters; it is an overestimation,
7878
// since we don't care about all the callables, so it
7979
// should be restricted more
80-
exists(CSharp::Callable callable | callable.getNumberOfParameters() = argIndex)
80+
argIndex in [0..any(CSharp::Callable c).getNumberOfParameters() - 1]
8181
}
8282

8383
predicate hasAsmOperandIndex(int operandIndex) { none() }

0 commit comments

Comments
 (0)