diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplSpecific.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplSpecific.qll index 07d3a0842c9bd..362537068a63a 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplSpecific.qll @@ -46,10 +46,6 @@ module CfgInput implements InputSig { CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) } - class SplitKindBase = Splitting::TSplitKind; - - class Split = Splitting::Split; - class SuccessorType = Cfg::SuccessorType; /** Gets a successor type that matches completion `c`. */ @@ -88,4 +84,19 @@ module CfgInput implements InputSig { } } -module CfgImpl = Make; +private module CfgSplittingInput implements SplittingInputSig { + private import Splitting as S + + class SplitKindBase = S::TSplitKind; + + class Split = S::Split; +} + +private module ConditionalCompletionSplittingInput implements + ConditionalCompletionSplittingInputSig +{ + import Splitting::ConditionalCompletionSplitting::ConditionalCompletionSplittingInput +} + +module CfgImpl = + MakeWithSplitting; diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Splitting.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Splitting.qll index dcc34ceb46b60..ddf2f01a8d41e 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Splitting.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Splitting.qll @@ -26,7 +26,7 @@ class Split extends TSplit { string toString() { none() } } -private module ConditionalCompletionSplitting { +module ConditionalCompletionSplitting { /** A split for conditional completions. */ class ConditionalCompletionSplit extends Split, TConditionalCompletionSplit { ConditionalCompletion completion; @@ -38,7 +38,7 @@ private module ConditionalCompletionSplitting { override string toString() { result = completion.toString() } } - private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind { + private class ConditionalCompletionSplitKind_ extends SplitKind, TConditionalCompletionSplitKind { override int getListOrder() { result = 0 } override predicate isEnabled(ControlFlowElement n) { this.appliesTo(n) } @@ -46,54 +46,44 @@ private module ConditionalCompletionSplitting { override string toString() { result = "ConditionalCompletion" } } - private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit - { - override ConditionalCompletionSplitKind getKind() { any() } + module ConditionalCompletionSplittingInput { + private import Completion as Comp - override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - succ(pred, succ, c) and - last(succ, _, super.getCompletion()) and + class ConditionalCompletion = Comp::ConditionalCompletion; + + class ConditionalCompletionSplitKind extends ConditionalCompletionSplitKind_, TSplitKind { } + + class ConditionalCompletionSplit = ConditionalCompletionSplitting::ConditionalCompletionSplit; + + bindingset[parent, parentCompletion] + private predicate condPropagateAstExpr( + AstNode parent, ConditionalCompletion parentCompletion, AstNode child, + ConditionalCompletion childCompletion + ) { + child = parent.(NotExpr).getOperand().getFullyConverted() and + childCompletion.(BooleanCompletion).getDual() = parentCompletion + or + childCompletion = parentCompletion and ( - astLast(succ.asAstNode().(NotExpr).getOperand().getFullyConverted(), pred, c) and - super.getCompletion().(BooleanCompletion).getDual() = c + child = parent.(LogicalAndExpr).getAnOperand().getFullyConverted() or - astLast(succ.asAstNode().(LogicalAndExpr).getAnOperand().getFullyConverted(), pred, c) and - super.getCompletion() = c + child = parent.(LogicalOrExpr).getAnOperand().getFullyConverted() or - astLast(succ.asAstNode().(LogicalOrExpr).getAnOperand().getFullyConverted(), pred, c) and - super.getCompletion() = c + child = parent.(IfExpr).getBranch(_).getFullyConverted() or - succ.asAstNode() = - any(IfExpr ce | - astLast(ce.getBranch(_).getFullyConverted(), pred, c) and - super.getCompletion() = c - ) - or - exists(Expr e, Exprs::Conversions::ConversionOrIdentityTree conv | - succ.asAstNode() = conv.getAst() and - conv.convertsFrom(e) and - astLast(e, pred, c) and - super.getCompletion() = c + exists(Exprs::Conversions::ConversionOrIdentityTree conv | + parent = conv.getAst() and + conv.convertsFrom(child) ) ) } - override predicate hasEntryScope(CfgInput::CfgScope scope, ControlFlowElement succ) { none() } - - override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - this.appliesTo(pred) and - succ(pred, succ, c) and - if c instanceof ConditionalCompletion then super.getCompletion() = c else any() - } - - override predicate hasExitScope(CfgInput::CfgScope scope, ControlFlowElement last, Completion c) { - this.appliesTo(last) and - succExit(scope, last, c) and - if c instanceof ConditionalCompletion then super.getCompletion() = c else any() - } - - override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - none() + bindingset[parent, parentCompletion] + predicate condPropagateExpr( + ControlFlowElement parent, ConditionalCompletion parentCompletion, ControlFlowElement child, + ConditionalCompletion childCompletion + ) { + condPropagateAstExpr(parent.asAstNode(), parentCompletion, child.asAstNode(), childCompletion) } } }