@@ -12,7 +12,6 @@ private import codeql.rust.elements.Call
1212private import SsaImpl as SsaImpl
1313private import codeql.rust.controlflow.internal.Scope as Scope
1414private import codeql.rust.internal.PathResolution
15- private import codeql.rust.internal.TypeInference as TypeInference
1615private import codeql.rust.controlflow.ControlFlowGraph
1716private import codeql.rust.dataflow.Ssa
1817private import codeql.rust.dataflow.FlowSummary
@@ -58,8 +57,8 @@ final class DataFlowCallable extends TDataFlowCallable {
5857}
5958
6059final class DataFlowCall extends TDataFlowCall {
61- /** Gets the underlying call in the CFG , if any. */
62- Call asCall ( ) { this = TCall ( result ) }
60+ /** Gets the underlying function call , if any. */
61+ FunctionCall asFunctionCall ( ) { this = TFunctionCall ( result ) }
6362
6463 predicate isSummaryCall (
6564 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
@@ -68,13 +67,13 @@ final class DataFlowCall extends TDataFlowCall {
6867 }
6968
7069 DataFlowCallable getEnclosingCallable ( ) {
71- result .asCfgScope ( ) = this .asCall ( ) .getEnclosingCfgScope ( )
70+ result .asCfgScope ( ) = this .asFunctionCall ( ) .getEnclosingCfgScope ( )
7271 or
7372 this .isSummaryCall ( result .asSummarizedCallable ( ) , _)
7473 }
7574
7675 string toString ( ) {
77- result = this .asCall ( ) .toString ( )
76+ result = this .asFunctionCall ( ) .toString ( )
7877 or
7978 exists (
8079 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
@@ -84,7 +83,7 @@ final class DataFlowCall extends TDataFlowCall {
8483 )
8584 }
8685
87- Location getLocation ( ) { result = this .asCall ( ) .getLocation ( ) }
86+ Location getLocation ( ) { result = this .asFunctionCall ( ) .getLocation ( ) }
8887}
8988
9089/**
@@ -133,26 +132,17 @@ final class ParameterPosition extends TParameterPosition {
133132final class ArgumentPosition extends ParameterPosition {
134133 /** Gets the argument of `call` at this position, if any. */
135134 Expr getArgument ( Call call ) {
136- result = call .getPositionalArgument ( this .getPosition ( ) )
135+ result = call .getArgument ( this .getPosition ( ) )
137136 or
138- result = call . getReceiver ( ) and this . isSelf ( )
137+ this . isSelf ( ) and result = call . getReceiver ( )
139138 }
140139}
141140
142141/**
143142 * Holds if `arg` is an argument of `call` at the position `pos`.
144- *
145- * Note that this does not hold for the receiever expression of a method call
146- * as the synthetic `ReceiverNode` is the argument for the `self` parameter.
147143 */
148- predicate isArgumentForCall ( Expr arg , Call call , ParameterPosition pos ) {
149- // TODO: Handle index expressions as calls in data flow.
150- not call instanceof IndexExpr and
151- (
152- call .getPositionalArgument ( pos .getPosition ( ) ) = arg
153- or
154- call .getReceiver ( ) = arg and pos .isSelf ( ) and not call .receiverImplicitlyBorrowed ( )
155- )
144+ predicate isArgumentForCall ( Expr arg , FunctionCall call , ArgumentPosition pos ) {
145+ arg = pos .getArgument ( call )
156146}
157147
158148/** Provides logic related to SSA. */
@@ -283,14 +273,6 @@ module LocalFlow {
283273 or
284274 nodeFrom .asPat ( ) .( OrPat ) .getAPat ( ) = nodeTo .asPat ( )
285275 or
286- // Simple value step from receiver expression to receiver node, in case
287- // there is no implicit deref or borrow operation.
288- nodeFrom .asExpr ( ) = nodeTo .( ReceiverNode ) .getReceiver ( )
289- or
290- // The dual step of the above, for the post-update nodes.
291- nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .( ReceiverNode ) .getReceiver ( ) =
292- nodeTo .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
293- or
294276 nodeTo .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) =
295277 getPostUpdateReverseStep ( nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) , true )
296278 }
@@ -309,10 +291,8 @@ predicate lambdaCreationExpr(Expr creation) {
309291 * Holds if `call` is a lambda call of kind `kind` where `receiver` is the
310292 * invoked expression.
311293 */
312- predicate lambdaCallExpr ( CallExpr call , LambdaCallKind kind , Expr receiver ) {
294+ predicate lambdaCallExpr ( ClosureCall call , LambdaCallKind kind , Expr receiver ) {
313295 receiver = call .getFunction ( ) and
314- // All calls to complex expressions and local variable accesses are lambda call.
315- ( receiver instanceof PathExpr implies receiver = any ( Variable v ) .getAnAccess ( ) ) and
316296 exists ( kind )
317297}
318298
@@ -380,7 +360,7 @@ module RustDataFlow implements InputSig<Location> {
380360 node .( FlowSummaryNode ) .getSummaryNode ( ) .isHidden ( ) or
381361 node instanceof CaptureNode or
382362 node instanceof ClosureParameterNode or
383- node instanceof ReceiverNode or
363+ node instanceof DerefBorrowNode or
384364 node .asExpr ( ) instanceof ParenExpr or
385365 nodeIsHidden ( node .( PostUpdateNode ) .getPreUpdateNode ( ) )
386366 }
@@ -422,7 +402,7 @@ module RustDataFlow implements InputSig<Location> {
422402
423403 /** Gets a viable implementation of the target of the given `Call`. */
424404 DataFlowCallable viableCallable ( DataFlowCall call ) {
425- exists ( Call c | c = call .asCall ( ) |
405+ exists ( FunctionCall c | c = call .asFunctionCall ( ) |
426406 result .asCfgScope ( ) = c .getARuntimeTarget ( )
427407 or
428408 exists ( SummarizedCallable sc , Function staticTarget |
@@ -520,16 +500,16 @@ module RustDataFlow implements InputSig<Location> {
520500 }
521501
522502 pragma [ nomagic]
523- private predicate implicitDerefToReceiver ( Node node1 , ReceiverNode node2 , ReferenceContent c ) {
524- TypeInference :: receiverHasImplicitDeref ( node1 . asExpr ( ) ) and
525- node1 .asExpr ( ) = node2 .getReceiver ( ) and
503+ private predicate implicitDeref ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
504+ not node2 . isBorrow ( ) and
505+ node1 .asExpr ( ) = node2 .getNode ( ) and
526506 exists ( c )
527507 }
528508
529509 pragma [ nomagic]
530- private predicate implicitBorrowToReceiver ( Node node1 , ReceiverNode node2 , ReferenceContent c ) {
531- TypeInference :: receiverHasImplicitBorrow ( node1 . asExpr ( ) ) and
532- node1 .asExpr ( ) = node2 .getReceiver ( ) and
510+ private predicate implicitBorrow ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
511+ node2 . isBorrow ( ) and
512+ node1 .asExpr ( ) = node2 .getNode ( ) and
533513 exists ( c )
534514 }
535515
@@ -539,6 +519,15 @@ module RustDataFlow implements InputSig<Location> {
539519 exists ( c )
540520 }
541521
522+ private Node getFieldExprContainerNode ( FieldExpr fe ) {
523+ exists ( Expr container | container = fe .getContainer ( ) |
524+ not any ( DerefBorrowNode n ) .getNode ( ) = container and
525+ result .asExpr ( ) = container
526+ or
527+ result .( DerefBorrowNode ) .getNode ( ) = container
528+ )
529+ }
530+
542531 pragma [ nomagic]
543532 additional predicate readContentStep ( Node node1 , Content c , Node node2 ) {
544533 exists ( TupleStructPat pat , int pos |
@@ -563,9 +552,9 @@ module RustDataFlow implements InputSig<Location> {
563552 node1 .asPat ( ) .( RefPat ) .getPat ( ) = node2 .asPat ( )
564553 or
565554 exists ( FieldExpr access |
566- node1 .asExpr ( ) = access .getContainer ( ) and
567555 node2 .asExpr ( ) = access and
568- access = c .( FieldContent ) .getAnAccess ( )
556+ access = c .( FieldContent ) .getAnAccess ( ) and
557+ node1 = getFieldExprContainerNode ( access )
569558 )
570559 or
571560 exists ( IndexExpr arr |
@@ -616,12 +605,10 @@ module RustDataFlow implements InputSig<Location> {
616605 referenceExprToExpr ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
617606 node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
618607 or
619- // Step from receiver expression to receiver node, in case of an implicit
620- // dereference.
621- implicitDerefToReceiver ( node1 , node2 , c )
608+ implicitDeref ( node1 , node2 , c )
622609 or
623610 // A read step dual to the store step for implicit borrows.
624- implicitBorrowToReceiver ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
611+ implicitBorrow ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
625612 node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
626613 or
627614 VariableCapture:: readStep ( node1 , c , node2 )
@@ -657,7 +644,7 @@ module RustDataFlow implements InputSig<Location> {
657644 exists ( AssignmentExpr assignment , FieldExpr access |
658645 assignment .getLhs ( ) = access and
659646 node1 .asExpr ( ) = assignment .getRhs ( ) and
660- node2 . asExpr ( ) = access . getContainer ( ) and
647+ node2 = getFieldExprContainerNode ( access ) and
661648 access = c .getAnAccess ( )
662649 )
663650 }
@@ -676,7 +663,7 @@ module RustDataFlow implements InputSig<Location> {
676663 pragma [ nomagic]
677664 additional predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
678665 exists ( CallExpr call , int pos |
679- node1 .asExpr ( ) = call .getArg ( pragma [ only_bind_into ] ( pos ) ) and
666+ node1 .asExpr ( ) = call .getArgument ( pragma [ only_bind_into ] ( pos ) ) and
680667 node2 .asExpr ( ) = call and
681668 c = TTupleFieldContent ( call .getTupleField ( pragma [ only_bind_into ] ( pos ) ) )
682669 )
@@ -729,9 +716,11 @@ module RustDataFlow implements InputSig<Location> {
729716 or
730717 VariableCapture:: storeStep ( node1 , c , node2 )
731718 or
732- // Step from receiver expression to receiver node, in case of an implicit
733- // borrow.
734- implicitBorrowToReceiver ( node1 , node2 , c )
719+ implicitBorrow ( node1 , node2 , c )
720+ or
721+ // A store step dual to the read step for implicit dereferences.
722+ implicitDeref ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
723+ node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
735724 }
736725
737726 /**
@@ -835,11 +824,7 @@ module RustDataFlow implements InputSig<Location> {
835824 */
836825 predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) {
837826 (
838- receiver .asExpr ( ) = call .asCall ( ) .( CallExpr ) .getFunction ( ) and
839- // All calls to complex expressions and local variable accesses are lambda call.
840- exists ( Expr f | f = receiver .asExpr ( ) |
841- f instanceof PathExpr implies f = any ( Variable v ) .getAnAccess ( )
842- )
827+ receiver .asExpr ( ) = call .asFunctionCall ( ) .( ClosureCall ) .getFunction ( )
843828 or
844829 call .isSummaryCall ( _, receiver .( FlowSummaryNode ) .getSummaryNode ( ) )
845830 ) and
@@ -1001,11 +986,9 @@ private module Cached {
1001986
1002987 cached
1003988 newtype TDataFlowCall =
1004- TCall ( Call call ) {
989+ TFunctionCall ( FunctionCall call ) {
1005990 Stages:: DataFlowStage:: ref ( ) and
1006- call .hasEnclosingCfgScope ( ) and
1007- // TODO: Handle index expressions as calls in data flow.
1008- not call instanceof IndexExpr
991+ call .hasEnclosingCfgScope ( )
1009992 } or
1010993 TSummaryCall (
1011994 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
@@ -1033,10 +1016,8 @@ private module Cached {
10331016 cached
10341017 newtype TParameterPosition =
10351018 TPositionalParameterPosition ( int i ) {
1036- i in [ 0 .. max ( [ any ( ParamList l ) .getNumberOfParams ( ) , any ( ArgList l ) .getNumberOfArgs ( ) ] ) - 1 ]
1037- or
1038- FlowSummaryImpl:: ParsePositions:: isParsedArgumentPosition ( _, i )
1039- or
1019+ i in [ 0 .. max ( [ any ( ParamList l ) .getNumberOfParams ( ) , any ( ArgList l ) .getNumberOfArgs ( ) ] ) - 1 ] or
1020+ FlowSummaryImpl:: ParsePositions:: isParsedArgumentPosition ( _, i ) or
10401021 FlowSummaryImpl:: ParsePositions:: isParsedParameterPosition ( _, i )
10411022 } or
10421023 TClosureSelfParameterPosition ( ) or
0 commit comments