@@ -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
@@ -47,7 +49,7 @@ final class DataFlowCallable extends TDataFlowCallable {
4749
4850 /** Gets a textual representation of this callable. */
4951 string toString ( ) {
50- result = [ this .asCfgScope ( ) .toString ( ) , this .asSummarizedCallable ( ) . toString ( ) ]
52+ result = [ this .asCfgScope ( ) .toString ( ) , "[summarized] " + this .asSummarizedCallable ( ) ]
5153 }
5254
5355 /** Gets the location of this callable. */
@@ -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/**
@@ -383,7 +400,8 @@ module RustDataFlow implements InputSig<Location> {
383400 node .( FlowSummaryNode ) .getSummaryNode ( ) .isHidden ( ) or
384401 node instanceof CaptureNode or
385402 node instanceof ClosureParameterNode or
386- node instanceof DerefBorrowNode or
403+ node instanceof ImplicitDerefNode or
404+ node instanceof ImplicitBorrowNode or
387405 node instanceof DerefOutNode or
388406 node instanceof IndexOutNode or
389407 node .asExpr ( ) instanceof ParenExpr or
@@ -443,25 +461,13 @@ module RustDataFlow implements InputSig<Location> {
443461 exists ( Call c | c = call .asCall ( ) |
444462 result .asCfgScope ( ) = c .getARuntimeTarget ( )
445463 or
446- exists ( SummarizedCallable sc , Function staticTarget |
447- staticTarget = getStaticTargetExt ( c ) and
448- sc = result .asSummarizedCallable ( ) and
449- // Only use summarized callables with generated summaries in case
450- // the static call target is not in the source code.
451- // Note that if `applyGeneratedModel` holds it implies that there doesn't
452- // exist a manual model.
453- not (
454- staticTarget .fromSource ( ) and
455- sc .applyGeneratedModel ( )
456- )
457- |
458- sc = staticTarget
459- or
460- // only apply trait models to concrete implementations when they are not
461- // defined in source code
462- staticTarget .implements ( sc ) and
463- not staticTarget .fromSource ( )
464- )
464+ result .asSummarizedCallable ( ) = getStaticTargetExt ( c )
465+ )
466+ or
467+ exists ( Function f | call = TImplicitDerefCall ( _, _, _, f ) |
468+ result .asCfgScope ( ) = f
469+ or
470+ result .asSummarizedCallable ( ) = f
465471 )
466472 }
467473
@@ -542,16 +548,18 @@ module RustDataFlow implements InputSig<Location> {
542548 }
543549
544550 pragma [ nomagic]
545- private predicate implicitDeref ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
546- not node2 .isBorrow ( ) and
547- node1 .asExpr ( ) = node2 .getNode ( ) and
551+ private predicate implicitDeref ( ImplicitDerefNode node1 , Node node2 , ReferenceContent c ) {
552+ node2 = node1 .getDerefOutputNode ( ) and
548553 exists ( c )
549554 }
550555
551556 pragma [ nomagic]
552- private predicate implicitBorrow ( Node node1 , DerefBorrowNode node2 , ReferenceContent c ) {
553- node2 .isBorrow ( ) and
554- node1 .asExpr ( ) = node2 .getNode ( ) and
557+ private predicate implicitBorrow ( Node node1 , Node node2 , ReferenceContent c ) {
558+ (
559+ node1 = node2 .( ImplicitDerefNode ) .getBorrowInputNode ( )
560+ or
561+ node1 = node2 .( ImplicitBorrowNode ) .getBorrowInputNode ( )
562+ ) and
555563 exists ( c )
556564 }
557565
@@ -563,10 +571,12 @@ module RustDataFlow implements InputSig<Location> {
563571
564572 private Node getFieldExprContainerNode ( FieldExpr fe ) {
565573 exists ( Expr container | container = fe .getContainer ( ) |
566- not any ( DerefBorrowNode n ) . getNode ( ) = container and
574+ not TypeInference :: implicitDerefChainBorrow ( container , _ , _ ) and
567575 result .asExpr ( ) = container
568576 or
569- result .( DerefBorrowNode ) .getNode ( ) = container
577+ result .( ImplicitBorrowNode ) .getNode ( ) = container
578+ or
579+ result .( ImplicitDerefNode ) .isLast ( container )
570580 )
571581 }
572582
@@ -1055,6 +1065,10 @@ private module Cached {
10551065 Stages:: DataFlowStage:: ref ( ) and
10561066 call .hasEnclosingCfgScope ( )
10571067 } or
1068+ TImplicitDerefCall ( AstNode n , DerefChain derefChain , int i , Function target ) {
1069+ TypeInference:: implicitDerefChainBorrow ( n , derefChain , _) and
1070+ target = derefChain .getElement ( i ) .getDerefFunction ( )
1071+ } or
10581072 TSummaryCall (
10591073 FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
10601074 ) {
0 commit comments