Skip to content

Commit bdb793b

Browse files
committed
Swift: Adopt shared ConditionalCompletionSplitting implementation
1 parent 3a098d7 commit bdb793b

File tree

2 files changed

+47
-46
lines changed

2 files changed

+47
-46
lines changed

swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplSpecific.qll

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ module CfgInput implements InputSig<Location> {
4646

4747
CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) }
4848

49-
class SplitKindBase = Splitting::TSplitKind;
50-
51-
class Split = Splitting::Split;
52-
5349
class SuccessorType = Cfg::SuccessorType;
5450

5551
/** Gets a successor type that matches completion `c`. */
@@ -88,4 +84,19 @@ module CfgInput implements InputSig<Location> {
8884
}
8985
}
9086

91-
module CfgImpl = Make<Location, CfgInput>;
87+
private module CfgSplittingInput implements SplittingInputSig<Location, CfgInput> {
88+
private import Splitting as S
89+
90+
class SplitKindBase = S::TSplitKind;
91+
92+
class Split = S::Split;
93+
}
94+
95+
private module ConditionalCompletionSplittingInput implements
96+
ConditionalCompletionSplittingInputSig<Location, CfgInput, CfgSplittingInput>
97+
{
98+
import Splitting::ConditionalCompletionSplitting::ConditionalCompletionSplittingInput
99+
}
100+
101+
module CfgImpl =
102+
MakeWithSplitting<Location, CfgInput, CfgSplittingInput, ConditionalCompletionSplittingInput>;

swift/ql/lib/codeql/swift/controlflow/internal/Splitting.qll

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Split extends TSplit {
2626
string toString() { none() }
2727
}
2828

29-
private module ConditionalCompletionSplitting {
29+
module ConditionalCompletionSplitting {
3030
/** A split for conditional completions. */
3131
class ConditionalCompletionSplit extends Split, TConditionalCompletionSplit {
3232
ConditionalCompletion completion;
@@ -38,62 +38,52 @@ private module ConditionalCompletionSplitting {
3838
override string toString() { result = completion.toString() }
3939
}
4040

41-
private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind {
41+
private class ConditionalCompletionSplitKind_ extends SplitKind, TConditionalCompletionSplitKind {
4242
override int getListOrder() { result = 0 }
4343

4444
override predicate isEnabled(ControlFlowElement n) { this.appliesTo(n) }
4545

4646
override string toString() { result = "ConditionalCompletion" }
4747
}
4848

49-
private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit
50-
{
51-
override ConditionalCompletionSplitKind getKind() { any() }
49+
module ConditionalCompletionSplittingInput {
50+
private import Completion as Comp
5251

53-
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
54-
succ(pred, succ, c) and
55-
last(succ, _, super.getCompletion()) and
52+
class ConditionalCompletion = Comp::ConditionalCompletion;
53+
54+
class ConditionalCompletionSplitKind extends ConditionalCompletionSplitKind_, TSplitKind { }
55+
56+
class ConditionalCompletionSplit = ConditionalCompletionSplitting::ConditionalCompletionSplit;
57+
58+
bindingset[parent, parentCompletion]
59+
private predicate condPropagateAstExpr(
60+
AstNode parent, ConditionalCompletion parentCompletion, AstNode child,
61+
ConditionalCompletion childCompletion
62+
) {
63+
child = parent.(NotExpr).getOperand().getFullyConverted() and
64+
childCompletion.(BooleanCompletion).getDual() = parentCompletion
65+
or
66+
childCompletion = parentCompletion and
5667
(
57-
astLast(succ.asAstNode().(NotExpr).getOperand().getFullyConverted(), pred, c) and
58-
super.getCompletion().(BooleanCompletion).getDual() = c
68+
child = parent.(LogicalAndExpr).getAnOperand().getFullyConverted()
5969
or
60-
astLast(succ.asAstNode().(LogicalAndExpr).getAnOperand().getFullyConverted(), pred, c) and
61-
super.getCompletion() = c
70+
child = parent.(LogicalOrExpr).getAnOperand().getFullyConverted()
6271
or
63-
astLast(succ.asAstNode().(LogicalOrExpr).getAnOperand().getFullyConverted(), pred, c) and
64-
super.getCompletion() = c
72+
child = parent.(IfExpr).getBranch(_).getFullyConverted()
6573
or
66-
succ.asAstNode() =
67-
any(IfExpr ce |
68-
astLast(ce.getBranch(_).getFullyConverted(), pred, c) and
69-
super.getCompletion() = c
70-
)
71-
or
72-
exists(Expr e, Exprs::Conversions::ConversionOrIdentityTree conv |
73-
succ.asAstNode() = conv.getAst() and
74-
conv.convertsFrom(e) and
75-
astLast(e, pred, c) and
76-
super.getCompletion() = c
74+
exists(Exprs::Conversions::ConversionOrIdentityTree conv |
75+
parent = conv.getAst() and
76+
conv.convertsFrom(child)
7777
)
7878
)
7979
}
8080

81-
override predicate hasEntryScope(CfgInput::CfgScope scope, ControlFlowElement succ) { none() }
82-
83-
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
84-
this.appliesTo(pred) and
85-
succ(pred, succ, c) and
86-
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
87-
}
88-
89-
override predicate hasExitScope(CfgInput::CfgScope scope, ControlFlowElement last, Completion c) {
90-
this.appliesTo(last) and
91-
succExit(scope, last, c) and
92-
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
93-
}
94-
95-
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
96-
none()
81+
bindingset[parent, parentCompletion]
82+
predicate condPropagateExpr(
83+
ControlFlowElement parent, ConditionalCompletion parentCompletion, ControlFlowElement child,
84+
ConditionalCompletion childCompletion
85+
) {
86+
condPropagateAstExpr(parent.asAstNode(), parentCompletion, child.asAstNode(), childCompletion)
9787
}
9888
}
9989
}

0 commit comments

Comments
 (0)