Skip to content

Commit 5d925d3

Browse files
committed
C#: Adopt shared ConditionalCompletionSplitting implementation
1 parent 3d95369 commit 5d925d3

File tree

2 files changed

+61
-74
lines changed

2 files changed

+61
-74
lines changed

csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ private predicate idOf(AstNode x, int y) = equivalenceRelation(id/2)(x, y)
5353
private module CfgInput implements CfgShared::InputSig<Location> {
5454
private import ControlFlowGraphImpl as Impl
5555
private import Completion as Comp
56-
private import Splitting as Splitting
5756
private import SuccessorType as ST
5857
private import semmle.code.csharp.Caching
5958

@@ -80,10 +79,6 @@ private module CfgInput implements CfgShared::InputSig<Location> {
8079
Impl::scopeLast(scope, last, c)
8180
}
8281

83-
class SplitKindBase = Splitting::TSplitKind;
84-
85-
class Split = Splitting::Split;
86-
8782
class SuccessorType = ST::SuccessorType;
8883

8984
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
@@ -102,7 +97,21 @@ private module CfgInput implements CfgShared::InputSig<Location> {
10297
}
10398
}
10499

105-
import CfgShared::Make<Location, CfgInput>
100+
private module CfgSplittingInput implements CfgShared::SplittingInputSig<Location, CfgInput> {
101+
private import Splitting as S
102+
103+
class SplitKindBase = S::TSplitKind;
104+
105+
class Split = S::Split;
106+
}
107+
108+
private module ConditionalCompletionSplittingInput implements
109+
CfgShared::ConditionalCompletionSplittingInputSig<Location, CfgInput, CfgSplittingInput>
110+
{
111+
import Splitting::ConditionalCompletionSplitting::ConditionalCompletionSplittingInput
112+
}
113+
114+
import CfgShared::MakeWithSplitting<Location, CfgInput, CfgSplittingInput, ConditionalCompletionSplittingInput>
106115

107116
/**
108117
* A compilation.

csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
*/
66

77
import csharp
8-
private import Completion
8+
private import Completion as Comp
9+
private import Comp
910
private import ControlFlowGraphImpl
1011
private import semmle.code.csharp.controlflow.ControlFlowGraph::ControlFlow as Cfg
1112
private import semmle.code.csharp.controlflow.internal.PreSsa
@@ -260,100 +261,77 @@ module ConditionalCompletionSplitting {
260261

261262
ConditionalCompletionSplit() { this = TConditionalCompletionSplit(completion) }
262263

264+
ConditionalCompletion getCompletion() { result = completion }
265+
263266
override string toString() { result = completion.toString() }
264267
}
265268

266-
private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind {
269+
private class ConditionalCompletionSplitKind_ extends SplitKind, TConditionalCompletionSplitKind {
267270
override int getListOrder() { result = InitializerSplitting::getNextListOrder() }
268271

269272
override predicate isEnabled(AstNode cfe) { this.appliesTo(cfe) }
270273

271274
override string toString() { result = "ConditionalCompletion" }
272275
}
273276

274-
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
277+
module ConditionalCompletionSplittingInput {
278+
private import Completion as Comp
275279

276-
private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit
277-
{
278-
ConditionalCompletion completion;
280+
class ConditionalCompletion = Comp::ConditionalCompletion;
279281

280-
ConditionalCompletionSplitImpl() { this = TConditionalCompletionSplit(completion) }
282+
class ConditionalCompletionSplitKind extends ConditionalCompletionSplitKind_, TSplitKind { }
281283

282-
override ConditionalCompletionSplitKind getKind() { any() }
284+
class ConditionalCompletionSplit = ConditionalCompletionSplitting::ConditionalCompletionSplit;
283285

284-
override predicate hasEntry(AstNode pred, AstNode succ, Completion c) {
285-
succ(pred, succ, c) and
286-
last(succ, _, completion) and
286+
bindingset[parent, parentCompletion]
287+
predicate condPropagateExpr(
288+
AstNode parent, ConditionalCompletion parentCompletion, AstNode child,
289+
ConditionalCompletion childCompletion
290+
) {
291+
child = parent.(LogicalNotExpr).getOperand() and
292+
childCompletion.getDual() = parentCompletion
293+
or
294+
childCompletion = parentCompletion and
287295
(
288-
last(succ.(LogicalNotExpr).getOperand(), pred, c) and
289-
completion.(BooleanCompletion).getDual() = c
296+
child = parent.(LogicalAndExpr).getAnOperand()
290297
or
291-
last(succ.(LogicalAndExpr).getAnOperand(), pred, c) and
292-
completion = c
298+
child = parent.(LogicalOrExpr).getAnOperand()
293299
or
294-
last(succ.(LogicalOrExpr).getAnOperand(), pred, c) and
295-
completion = c
300+
parent = any(ConditionalExpr ce | child = [ce.getThen(), ce.getElse()])
296301
or
297-
succ =
298-
any(ConditionalExpr ce |
299-
last([ce.getThen(), ce.getElse()], pred, c) and
300-
completion = c
301-
)
302+
child = parent.(SwitchExpr).getACase()
302303
or
303-
succ =
304+
child = parent.(SwitchCaseExpr).getBody()
305+
or
306+
parent =
304307
any(NullCoalescingExpr nce |
305-
exists(Expr operand |
306-
last(operand, pred, c) and
307-
completion = c
308-
|
309-
if c instanceof NullnessCompletion
310-
then operand = nce.getRightOperand()
311-
else operand = nce.getAnOperand()
312-
)
308+
if childCompletion instanceof NullnessCompletion
309+
then child = nce.getRightOperand()
310+
else child = nce.getAnOperand()
313311
)
312+
)
313+
or
314+
child = parent.(NotPatternExpr).getPattern() and
315+
childCompletion.getDual() = parentCompletion
316+
or
317+
child = parent.(IsExpr).getPattern() and
318+
parentCompletion.(BooleanCompletion).getValue() =
319+
childCompletion.(MatchingCompletion).getValue()
320+
or
321+
childCompletion = parentCompletion and
322+
(
323+
child = parent.(AndPatternExpr).getAnOperand()
314324
or
315-
last(succ.(SwitchExpr).getACase(), pred, c) and
316-
completion = c
317-
or
318-
last(succ.(SwitchCaseExpr).getBody(), pred, c) and
319-
completion = c
320-
or
321-
last(succ.(NotPatternExpr).getPattern(), pred, c) and
322-
completion.(MatchingCompletion).getDual() = c
323-
or
324-
last(succ.(IsExpr).getPattern(), pred, c) and
325-
completion.(BooleanCompletion).getValue() = c.(MatchingCompletion).getValue()
326-
or
327-
last(succ.(AndPatternExpr).getAnOperand(), pred, c) and
328-
completion = c
329-
or
330-
last(succ.(OrPatternExpr).getAnOperand(), pred, c) and
331-
completion = c
325+
child = parent.(OrPatternExpr).getAnOperand()
332326
or
333-
last(succ.(RecursivePatternExpr).getAChildExpr(), pred, c) and
334-
completion = c
327+
child = parent.(RecursivePatternExpr).getAChildExpr()
335328
or
336-
last(succ.(PropertyPatternExpr).getPattern(_), pred, c) and
337-
completion = c
329+
child = parent.(PropertyPatternExpr).getPattern(_)
338330
)
339331
}
340-
341-
override predicate hasEntryScope(CfgScope scope, AstNode first) { none() }
342-
343-
override predicate hasExit(AstNode pred, AstNode succ, Completion c) {
344-
this.appliesTo(pred) and
345-
succ(pred, succ, c) and
346-
if c instanceof ConditionalCompletion then completion = c else any()
347-
}
348-
349-
override predicate hasExitScope(CfgScope scope, AstNode last, Completion c) {
350-
this.appliesTo(last) and
351-
scopeLast(scope, last, c) and
352-
if c instanceof ConditionalCompletion then completion = c else any()
353-
}
354-
355-
override predicate hasSuccessor(AstNode pred, AstNode succ, Completion c) { none() }
356332
}
333+
334+
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
357335
}
358336

359337
module AssertionSplitting {

0 commit comments

Comments
 (0)