Skip to content

Commit 4bd9473

Browse files
committed
unified: Split up hasControlFlowPosition()
1 parent 6444d0b commit 4bd9473

1 file changed

Lines changed: 55 additions & 38 deletions

File tree

‎unified/ql/lib/codeql/unified/internal/dataflow/DataFlowNode.qll‎

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,50 @@ class BuilderNode extends TDataFlowNodeStage1 {
320320
result = call.getLocation()
321321
)
322322
}
323+
324+
/**
325+
* Holds if this data flow node is associated with the `i`'th index in the given basic block.
326+
*
327+
* Note that some data flow nodes may have an index appearing before the first or after the
328+
* last `ControlFlowNode` node in the basic block. Multiple data flow nodes may share the same control flow position.
329+
*
330+
* Also note that some data flow nodes have no associated control flow position, either because they are
331+
* in unreachable code, or belong to a synthesized callable that has no control flow graph.
332+
*/
333+
predicate hasControlFlowPosition(BasicBlock bb, int i) {
334+
exists(ControlFlowNode cfgNode | cfgNode = bb.getNode(i) |
335+
exists(Expr expr |
336+
this.isResultValue(expr) and cfgNode.asExpr() = expr
337+
or
338+
this.isIncomingValue(expr) and hasIncomingValueAtCfgNode(expr, cfgNode)
339+
or
340+
this.isPostUpdate(expr) and hasPostUpdate(expr, cfgNode)
341+
)
342+
or
343+
exists(AstNode repr, LocalVariable var, VariableRefKind kind |
344+
this.isLocalVariableRef(repr, var, kind) and
345+
performsVariableAccess(repr, var, kind, cfgNode)
346+
)
347+
or
348+
exists(DataFlowCallable callable |
349+
this.isImplicitParameter(callable, _) and
350+
cfgNode.(ControlFlow::EntryNode).getEnclosingCallable() = callable.asSourceCallable()
351+
or
352+
this.isCallableEx(callable) and
353+
cfgNode.injects(callable.asSourceCallable())
354+
)
355+
or
356+
exists(DataFlowCall call, CallExpr sourceCall, boolean isPost |
357+
call.asExplicitCall() = sourceCall and
358+
this.isImplicitArgument(call, _, isPost) and
359+
(
360+
isPost = false and cfgNode.injects(sourceCall)
361+
or
362+
isPost = true and cfgNode.isAfter(sourceCall)
363+
)
364+
)
365+
)
366+
}
323367
}
324368

325369
/** A node in stage 2, which includes stage 1 and local SSA nodes. */
@@ -343,6 +387,16 @@ class Stage2Node extends TDataFlowNodeStage2 {
343387
result = node.getLocation()
344388
)
345389
}
390+
391+
predicate hasControlFlowPosition(BasicBlock bb, int i) {
392+
this.(BuilderNode).hasControlFlowPosition(bb, i)
393+
or
394+
exists(LocalSsaDataFlowOutput::SsaNode node |
395+
this = TLocalSsaNode(node) and
396+
bb = node.getBasicBlock() and
397+
i = node.getIndex() // TODO: why is this marked as internal in the SSA library?
398+
)
399+
}
346400
}
347401

348402
class Node extends TDataFlowNode {
@@ -491,44 +545,7 @@ class Node extends TDataFlowNode {
491545
* in unreachable code, or belong to a synthesized callable that has no control flow graph.
492546
*/
493547
predicate hasControlFlowPosition(BasicBlock bb, int i) {
494-
exists(ControlFlowNode cfgNode | cfgNode = bb.getNode(i) |
495-
exists(Expr expr |
496-
this.isResultValue(expr) and cfgNode.asExpr() = expr
497-
or
498-
this.isIncomingValue(expr) and hasIncomingValueAtCfgNode(expr, cfgNode)
499-
or
500-
this.isPostUpdate(expr) and hasPostUpdate(expr, cfgNode)
501-
)
502-
or
503-
exists(AstNode repr, LocalVariable var, VariableRefKind kind |
504-
this.isLocalVariableRef(repr, var, kind) and
505-
performsVariableAccess(repr, var, kind, cfgNode)
506-
)
507-
or
508-
exists(DataFlowCallable callable |
509-
this.(BuilderNode).isImplicitParameter(callable, _) and
510-
cfgNode.(ControlFlow::EntryNode).getEnclosingCallable() = callable.asSourceCallable()
511-
or
512-
this.isCallableEx(callable) and
513-
cfgNode.injects(callable.asSourceCallable())
514-
)
515-
or
516-
exists(DataFlowCall call, CallExpr sourceCall, boolean isPost |
517-
call.asExplicitCall() = sourceCall and
518-
this.(BuilderNode).isImplicitArgument(call, _, isPost) and
519-
(
520-
isPost = false and cfgNode.injects(sourceCall)
521-
or
522-
isPost = true and cfgNode.isAfter(sourceCall)
523-
)
524-
)
525-
)
526-
or
527-
exists(LocalSsaDataFlowOutput::SsaNode node |
528-
this = TLocalSsaNode(node) and
529-
bb = node.getBasicBlock() and
530-
i = node.getIndex() // TODO: why is this marked as internal in the SSA library?
531-
)
548+
this.(Stage2Node).hasControlFlowPosition(bb, i)
532549
or
533550
exists(CaptureSsaOutput::SynthesizedCaptureNode node |
534551
this = TCaptureSsaNode(node) and

0 commit comments

Comments
 (0)