@@ -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 isImplicitDeref ( 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,19 @@ final class DataFlowCall extends TDataFlowCall {
6975 DataFlowCallable getEnclosingCallable ( ) {
7076 result .asCfgScope ( ) = this .asCall ( ) .getEnclosingCfgScope ( )
7177 or
78+ result .asCfgScope ( ) = any ( AstNode n | this .isImplicitDeref ( n , _, _, _) ) .getEnclosingCfgScope ( )
79+ or
7280 this .isSummaryCall ( result .asSummarizedCallable ( ) , _)
7381 }
7482
7583 string toString ( ) {
7684 result = this .asCall ( ) .toString ( )
7785 or
86+ exists ( AstNode n , DerefChain derefChain , int i , Function target |
87+ this .isImplicitDeref ( n , derefChain , i , target ) and
88+ result = "[implicit deref call " + i + " in " + derefChain .toString ( ) + "] " + n
89+ )
90+ or
7891 exists (
7992 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
8093 |
@@ -83,7 +96,11 @@ final class DataFlowCall extends TDataFlowCall {
8396 )
8497 }
8598
86- Location getLocation ( ) { result = this .asCall ( ) .getLocation ( ) }
99+ Location getLocation ( ) {
100+ result = this .asCall ( ) .getLocation ( )
101+ or
102+ result = any ( AstNode n | this .isImplicitDeref ( n , _, _, _) ) .getLocation ( )
103+ }
87104}
88105
89106/**
@@ -257,6 +274,8 @@ private module Aliases {
257274
258275 class ContentAlias = Content ;
259276
277+ class ContentApproxAlias = ContentApprox ;
278+
260279 class ContentSetAlias = ContentSet ;
261280
262281 class LambdaCallKindAlias = LambdaCallKind ;
@@ -383,7 +402,8 @@ module RustDataFlow implements InputSig<Location> {
383402 node .( FlowSummaryNode ) .getSummaryNode ( ) .isHidden ( ) or
384403 node instanceof CaptureNode or
385404 node instanceof ClosureParameterNode or
386- node instanceof DerefBorrowNode or
405+ node instanceof ImplicitDerefNode or
406+ node instanceof ImplicitBorrowNode or
387407 node instanceof DerefOutNode or
388408 node instanceof IndexOutNode or
389409 node .asExpr ( ) instanceof ParenExpr or
@@ -445,6 +465,12 @@ module RustDataFlow implements InputSig<Location> {
445465 or
446466 result .asSummarizedCallable ( ) = getStaticTargetExt ( c )
447467 )
468+ or
469+ exists ( Function f | call = TImplicitDerefCall ( _, _, _, f ) |
470+ result .asCfgScope ( ) = f
471+ or
472+ result .asSummarizedCallable ( ) = f
473+ )
448474 }
449475
450476 /**
@@ -471,9 +497,27 @@ module RustDataFlow implements InputSig<Location> {
471497
472498 predicate forceHighPrecision ( Content c ) { none ( ) }
473499
474- final class ContentApprox = Content ; // TODO: Implement if needed
500+ class ContentApprox = ContentApproxAlias ;
475501
476- ContentApprox getContentApprox ( Content c ) { result = c }
502+ ContentApprox getContentApprox ( Content c ) {
503+ result = TTupleFieldContentApprox ( tupleFieldApprox ( c .( TupleFieldContent ) .getField ( ) ) )
504+ or
505+ result = TStructFieldContentApprox ( structFieldApprox ( c .( StructFieldContent ) .getField ( ) ) )
506+ or
507+ result = TElementContentApprox ( ) and c instanceof ElementContent
508+ or
509+ result = TFutureContentApprox ( ) and c instanceof FutureContent
510+ or
511+ result = TTuplePositionContentApprox ( ) and c instanceof TuplePositionContent
512+ or
513+ result = TFunctionCallArgumentContentApprox ( ) and c instanceof FunctionCallArgumentContent
514+ or
515+ result = TFunctionCallReturnContentApprox ( ) and c instanceof FunctionCallReturnContent
516+ or
517+ result = TCapturedVariableContentApprox ( ) and c instanceof CapturedVariableContent
518+ or
519+ result = TReferenceContentApprox ( ) and c instanceof ReferenceContent
520+ }
477521
478522 /**
479523 * Holds if the parameter position `ppos` matches the argument position
@@ -499,6 +543,8 @@ module RustDataFlow implements InputSig<Location> {
499543 not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom , _)
500544 )
501545 or
546+ nodeFrom = nodeTo .( ImplicitDerefNode ) .getLocalInputNode ( )
547+ or
502548 VariableCapture:: localFlowStep ( nodeFrom , nodeTo )
503549 ) and
504550 model = ""
@@ -524,16 +570,18 @@ module RustDataFlow implements InputSig<Location> {
524570 }
525571
526572 pragma [ nomagic]
527- private predicate implicitDeref ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
528- not node2 .isBorrow ( ) and
529- node1 .asExpr ( ) = node2 .getNode ( ) and
573+ private predicate implicitDeref ( ImplicitDerefNode node1 , Node node2 , ReferenceContent c ) {
574+ node2 = node1 .getDerefOutputNode ( ) and
530575 exists ( c )
531576 }
532577
533578 pragma [ nomagic]
534- private predicate implicitBorrow ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
535- node2 .isBorrow ( ) and
536- node1 .asExpr ( ) = node2 .getNode ( ) and
579+ private predicate implicitBorrow ( Node node1 , Node node2 , ReferenceContent c ) {
580+ (
581+ node1 = node2 .( ImplicitDerefNode ) .getBorrowInputNode ( )
582+ or
583+ node1 = node2 .( ImplicitBorrowNode ) .getBorrowInputNode ( )
584+ ) and
537585 exists ( c )
538586 }
539587
@@ -545,10 +593,12 @@ module RustDataFlow implements InputSig<Location> {
545593
546594 private Node getFieldExprContainerNode ( FieldExpr fe ) {
547595 exists ( Expr container | container = fe .getContainer ( ) |
548- not any ( DerefBorrowNode n ) . getNode ( ) = container and
596+ not TypeInference :: implicitDerefChainBorrow ( container , _ , _ ) and
549597 result .asExpr ( ) = container
550598 or
551- result .( DerefBorrowNode ) .getNode ( ) = container
599+ result .( ImplicitBorrowNode ) .getNode ( ) = container
600+ or
601+ result .( ImplicitDerefNode ) .isLast ( container )
552602 )
553603 }
554604
@@ -1037,6 +1087,10 @@ private module Cached {
10371087 Stages:: DataFlowStage:: ref ( ) and
10381088 call .hasEnclosingCfgScope ( )
10391089 } or
1090+ TImplicitDerefCall ( AstNode n , DerefChain derefChain , int i , Function target ) {
1091+ TypeInference:: implicitDerefChainBorrow ( n , derefChain , _) and
1092+ target = derefChain .getElement ( i ) .getDerefFunction ( )
1093+ } or
10401094 TSummaryCall (
10411095 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
10421096 ) {
0 commit comments