Skip to content

Commit db213bb

Browse files
author
AndreiDiaconu1
committed
Fixed sanity checks
The foreach was erroneously labelling the `True` and `False` edges as backedges. Added a case for the compiler generated while in the predicate `getInstructionBackEdgeSuccessor/2` from the file `IRConstruction.qll` so that only the edges from inside the body are labeled as back edges.
1 parent 46d7b9e commit db213bb

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import TranslatedCondition
77
private import TranslatedElement
88
private import TranslatedExpr
99
private import TranslatedStmt
10+
private import desugar.Foreach
1011
private import TranslatedFunction
1112
private import semmle.code.csharp.ir.Util
1213
private import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
@@ -135,6 +136,18 @@ private module Cached {
135136
)
136137
)
137138
or
139+
// Compiler generated foreach while loop:
140+
// Same as above
141+
exists(TranslatedForeachWhile s |
142+
s instanceof TranslatedForeachWhile and
143+
result = s.getFirstInstruction() and
144+
exists(TranslatedElement inBody, InstructionTag tag |
145+
result = inBody.getInstructionSuccessor(tag, kind) and
146+
exists(TranslatedElement body | body = s.getBody() | inBody = body.getAChild*()) and
147+
instruction = inBody.getInstruction(tag)
148+
)
149+
)
150+
or
138151
// Do-while loop:
139152
// The back edge should be the edge(s) from the condition to the
140153
// body. This ensures that it's the back edge that will be pruned in a `do

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,10 @@ private class TranslatedForeachFinally extends TranslatedCompilerGeneratedBlock,
117117

118118
/**
119119
* The compiler generated while loop.
120+
* Note that this class is not private since it is needed in `IRConstruction.qll`,
121+
* to correctly mark which edges should be back edges.
120122
*/
121-
private class TranslatedForeachWhile extends TranslatedCompilerGeneratedStmt, ConditionContext,
123+
class TranslatedForeachWhile extends TranslatedCompilerGeneratedStmt, ConditionContext,
122124
TTranslatedCompilerGeneratedElement {
123125
override ForeachStmt generatedBy;
124126

@@ -159,18 +161,18 @@ private class TranslatedForeachWhile extends TranslatedCompilerGeneratedStmt, Co
159161
child = getCondition() and result = getParent().getChildSuccessor(this)
160162
}
161163

162-
private TranslatedStmt getBody() {
164+
TranslatedStmt getBody() {
163165
result = getTranslatedStmt(generatedBy.getBody())
164166
}
165167

166-
private TranslatedElement getInit() {
168+
TranslatedElement getInit() {
167169
exists(TranslatedForeachIterVar iv |
168170
iv.getAST() = generatedBy and
169171
result = iv
170172
)
171173
}
172174

173-
private ValueConditionBlueprint getCondition() {
175+
ValueConditionBlueprint getCondition() {
174176
exists(TranslatedForeachWhileCondition cond |
175177
cond.getAST() = generatedBy and
176178
result = cond

csharp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,8 @@ foreach.cs:
406406
# 7| r1_3(Boolean) = Call : func:r1_2, this:r1_1
407407
# 7| mu1_4(null) = ^CallSideEffect : ~mu0_2
408408
# 7| v1_5(Void) = ConditionalBranch : r1_3
409-
#-----| False (back edge) -> Block 3
410-
#-----| True (back edge) -> Block 2
409+
#-----| False -> Block 3
410+
#-----| True -> Block 2
411411

412412
# 7| Block 2
413413
# 7| r2_0(glval<Int32>) = VariableAddress[items] :

0 commit comments

Comments
 (0)