@@ -15,6 +15,8 @@ private import codeql.rust.internal.PathResolution
1515private import codeql.rust.controlflow.ControlFlowGraph
1616private import codeql.rust.dataflow.Ssa
1717private import codeql.rust.dataflow.FlowSummary
18+ private import codeql.rust.internal.TypeInference as TypeInference
19+ private import codeql.rust.internal.typeinference.DerefChain
1820private import Node
1921private import Content
2022private import FlowSummaryImpl as FlowSummaryImpl
@@ -60,6 +62,10 @@ final class DataFlowCall extends TDataFlowCall {
6062 /** Gets the underlying call, if any. */
6163 Call asCall ( ) { this = TCall ( result ) }
6264
65+ predicate isImplicitDerefCall ( AstNode n , DerefChain derefChain , int i , Function target ) {
66+ this = TImplicitDerefCall ( n , derefChain , i , target )
67+ }
68+
6369 predicate isSummaryCall (
6470 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
6571 ) {
@@ -69,12 +75,20 @@ final class DataFlowCall extends TDataFlowCall {
6975 DataFlowCallable getEnclosingCallable ( ) {
7076 result .asCfgScope ( ) = this .asCall ( ) .getEnclosingCfgScope ( )
7177 or
78+ result .asCfgScope ( ) =
79+ any ( AstNode n | this .isImplicitDerefCall ( n , _, _, _) ) .getEnclosingCfgScope ( )
80+ or
7281 this .isSummaryCall ( result .asSummarizedCallable ( ) , _)
7382 }
7483
7584 string toString ( ) {
7685 result = this .asCall ( ) .toString ( )
7786 or
87+ exists ( AstNode n , DerefChain derefChain , int i , Function target |
88+ this .isImplicitDerefCall ( n , derefChain , i , target ) and
89+ result = "[implicit deref call " + i + " in " + derefChain .toString ( ) + "] " + n
90+ )
91+ or
7892 exists (
7993 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
8094 |
@@ -83,7 +97,11 @@ final class DataFlowCall extends TDataFlowCall {
8397 )
8498 }
8599
86- Location getLocation ( ) { result = this .asCall ( ) .getLocation ( ) }
100+ Location getLocation ( ) {
101+ result = this .asCall ( ) .getLocation ( )
102+ or
103+ result = any ( AstNode n | this .isImplicitDerefCall ( n , _, _, _) ) .getLocation ( )
104+ }
87105}
88106
89107/**
@@ -257,6 +275,8 @@ private module Aliases {
257275
258276 class ContentAlias = Content ;
259277
278+ class ContentApproxAlias = ContentApprox ;
279+
260280 class ContentSetAlias = ContentSet ;
261281
262282 class LambdaCallKindAlias = LambdaCallKind ;
@@ -383,7 +403,8 @@ module RustDataFlow implements InputSig<Location> {
383403 node .( FlowSummaryNode ) .getSummaryNode ( ) .isHidden ( ) or
384404 node instanceof CaptureNode or
385405 node instanceof ClosureParameterNode or
386- node instanceof DerefBorrowNode or
406+ node instanceof ImplicitDerefNode or
407+ node instanceof ImplicitBorrowNode or
387408 node instanceof DerefOutNode or
388409 node instanceof IndexOutNode or
389410 node .asExpr ( ) instanceof ParenExpr or
@@ -445,6 +466,12 @@ module RustDataFlow implements InputSig<Location> {
445466 or
446467 result .asSummarizedCallable ( ) = getStaticTargetExt ( c )
447468 )
469+ or
470+ exists ( Function f | call = TImplicitDerefCall ( _, _, _, f ) |
471+ result .asCfgScope ( ) = f
472+ or
473+ result .asSummarizedCallable ( ) = f
474+ )
448475 }
449476
450477 /**
@@ -471,9 +498,27 @@ module RustDataFlow implements InputSig<Location> {
471498
472499 predicate forceHighPrecision ( Content c ) { none ( ) }
473500
474- final class ContentApprox = Content ; // TODO: Implement if needed
501+ class ContentApprox = ContentApproxAlias ;
475502
476- ContentApprox getContentApprox ( Content c ) { result = c }
503+ ContentApprox getContentApprox ( Content c ) {
504+ result = TTupleFieldContentApprox ( tupleFieldApprox ( c .( TupleFieldContent ) .getField ( ) ) )
505+ or
506+ result = TStructFieldContentApprox ( structFieldApprox ( c .( StructFieldContent ) .getField ( ) ) )
507+ or
508+ result = TElementContentApprox ( ) and c instanceof ElementContent
509+ or
510+ result = TFutureContentApprox ( ) and c instanceof FutureContent
511+ or
512+ result = TTuplePositionContentApprox ( ) and c instanceof TuplePositionContent
513+ or
514+ result = TFunctionCallArgumentContentApprox ( ) and c instanceof FunctionCallArgumentContent
515+ or
516+ result = TFunctionCallReturnContentApprox ( ) and c instanceof FunctionCallReturnContent
517+ or
518+ result = TCapturedVariableContentApprox ( ) and c instanceof CapturedVariableContent
519+ or
520+ result = TReferenceContentApprox ( ) and c instanceof ReferenceContent
521+ }
477522
478523 /**
479524 * Holds if the parameter position `ppos` matches the argument position
@@ -499,6 +544,8 @@ module RustDataFlow implements InputSig<Location> {
499544 not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom , _)
500545 )
501546 or
547+ nodeFrom = nodeTo .( ImplicitDerefNode ) .getLocalInputNode ( )
548+ or
502549 VariableCapture:: localFlowStep ( nodeFrom , nodeTo )
503550 ) and
504551 model = ""
@@ -524,16 +571,14 @@ module RustDataFlow implements InputSig<Location> {
524571 }
525572
526573 pragma [ nomagic]
527- private predicate implicitDeref ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
528- not node2 .isBorrow ( ) and
529- node1 .asExpr ( ) = node2 .getNode ( ) and
574+ private predicate implicitDeref ( ImplicitDerefNode node1 , Node node2 , ReferenceContent c ) {
575+ node2 = node1 .getDerefOutputNode ( ) and
530576 exists ( c )
531577 }
532578
533579 pragma [ nomagic]
534- private predicate implicitBorrow ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
535- node2 .isBorrow ( ) and
536- node1 .asExpr ( ) = node2 .getNode ( ) and
580+ private predicate implicitBorrow ( Node node1 , ImplicitDerefBorrowNode node2 , ReferenceContent c ) {
581+ node1 = node2 .getBorrowInputNode ( ) and
537582 exists ( c )
538583 }
539584
@@ -545,10 +590,10 @@ module RustDataFlow implements InputSig<Location> {
545590
546591 private Node getFieldExprContainerNode ( FieldExpr fe ) {
547592 exists ( Expr container | container = fe .getContainer ( ) |
548- not any ( DerefBorrowNode n ) . getNode ( ) = container and
593+ not TypeInference :: implicitDerefChainBorrow ( container , _ , _ ) and
549594 result .asExpr ( ) = container
550595 or
551- result .( DerefBorrowNode ) . getNode ( ) = container
596+ result .( ImplicitDerefNode ) . isLast ( container )
552597 )
553598 }
554599
@@ -1037,6 +1082,10 @@ private module Cached {
10371082 Stages:: DataFlowStage:: ref ( ) and
10381083 call .hasEnclosingCfgScope ( )
10391084 } or
1085+ TImplicitDerefCall ( AstNode n , DerefChain derefChain , int i , Function target ) {
1086+ TypeInference:: implicitDerefChainBorrow ( n , derefChain , _) and
1087+ target = derefChain .getElement ( i ) .getDerefFunction ( )
1088+ } or
10401089 TSummaryCall (
10411090 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
10421091 ) {
0 commit comments