@@ -523,97 +523,103 @@ module RustDataFlow implements InputSig<Location> {
523
523
exists ( c )
524
524
}
525
525
526
+ pragma [ nomagic]
527
+ additional predicate readContentStep ( Node node1 , Content c , Node node2 ) {
528
+ exists ( TupleStructPatCfgNode pat , int pos |
529
+ pat = node1 .asPat ( ) and
530
+ node2 .asPat ( ) = pat .getField ( pos ) and
531
+ c = TTupleFieldContent ( pat .getTupleStructPat ( ) .getTupleField ( pos ) )
532
+ )
533
+ or
534
+ exists ( TuplePatCfgNode pat , int pos |
535
+ pos = c .( TuplePositionContent ) .getPosition ( ) and
536
+ node1 .asPat ( ) = pat and
537
+ node2 .asPat ( ) = pat .getField ( pos )
538
+ )
539
+ or
540
+ exists ( StructPatCfgNode pat , string field |
541
+ pat = node1 .asPat ( ) and
542
+ c = TStructFieldContent ( pat .getStructPat ( ) .getStructField ( field ) ) and
543
+ node2 .asPat ( ) = pat .getFieldPat ( field )
544
+ )
545
+ or
546
+ c instanceof ReferenceContent and
547
+ node1 .asPat ( ) .( RefPatCfgNode ) .getPat ( ) = node2 .asPat ( )
548
+ or
549
+ exists ( FieldExprCfgNode access |
550
+ node1 .asExpr ( ) = access .getContainer ( ) and
551
+ node2 .asExpr ( ) = access and
552
+ access = c .( FieldContent ) .getAnAccess ( )
553
+ )
554
+ or
555
+ exists ( IndexExprCfgNode arr |
556
+ c instanceof ElementContent and
557
+ node1 .asExpr ( ) = arr .getBase ( ) and
558
+ node2 .asExpr ( ) = arr
559
+ )
560
+ or
561
+ exists ( ForExprCfgNode for |
562
+ c instanceof ElementContent and
563
+ node1 .asExpr ( ) = for .getIterable ( ) and
564
+ node2 .asPat ( ) = for .getPat ( )
565
+ )
566
+ or
567
+ exists ( SlicePatCfgNode pat |
568
+ c instanceof ElementContent and
569
+ node1 .asPat ( ) = pat and
570
+ node2 .asPat ( ) = pat .getAPat ( )
571
+ )
572
+ or
573
+ exists ( TryExprCfgNode try |
574
+ node1 .asExpr ( ) = try .getExpr ( ) and
575
+ node2 .asExpr ( ) = try and
576
+ c .( TupleFieldContent )
577
+ .isVariantField ( [ any ( OptionEnum o ) .getSome ( ) , any ( ResultEnum r ) .getOk ( ) ] , 0 )
578
+ )
579
+ or
580
+ exists ( PrefixExprCfgNode deref |
581
+ c instanceof ReferenceContent and
582
+ deref .getOperatorName ( ) = "*" and
583
+ node1 .asExpr ( ) = deref .getExpr ( ) and
584
+ node2 .asExpr ( ) = deref
585
+ )
586
+ or
587
+ // Read from function return
588
+ exists ( DataFlowCall call |
589
+ lambdaCall ( call , _, node1 ) and
590
+ call = node2 .( OutNode ) .getCall ( TNormalReturnKind ( ) ) and
591
+ c instanceof FunctionCallReturnContent
592
+ )
593
+ or
594
+ exists ( AwaitExprCfgNode await |
595
+ c instanceof FutureContent and
596
+ node1 .asExpr ( ) = await .getExpr ( ) and
597
+ node2 .asExpr ( ) = await
598
+ )
599
+ or
600
+ referenceExprToExpr ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
601
+ node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
602
+ or
603
+ // Step from receiver expression to receiver node, in case of an implicit
604
+ // dereference.
605
+ implicitDerefToReceiver ( node1 , node2 , c )
606
+ or
607
+ // A read step dual to the store step for implicit borrows.
608
+ implicitBorrowToReceiver ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
609
+ node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
610
+ or
611
+ VariableCapture:: readStep ( node1 , c , node2 )
612
+ }
613
+
526
614
/**
527
615
* Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
528
616
* `node1` references an object with a content `c.getAReadContent()` whose
529
617
* value ends up in `node2`.
530
618
*/
531
619
predicate readStep ( Node node1 , ContentSet cs , Node node2 ) {
532
- exists ( Content c | c = cs .( SingletonContentSet ) .getContent ( ) |
533
- exists ( TupleStructPatCfgNode pat , int pos |
534
- pat = node1 .asPat ( ) and
535
- node2 .asPat ( ) = pat .getField ( pos ) and
536
- c = TTupleFieldContent ( pat .getTupleStructPat ( ) .getTupleField ( pos ) )
537
- )
538
- or
539
- exists ( TuplePatCfgNode pat , int pos |
540
- pos = c .( TuplePositionContent ) .getPosition ( ) and
541
- node1 .asPat ( ) = pat and
542
- node2 .asPat ( ) = pat .getField ( pos )
543
- )
544
- or
545
- exists ( StructPatCfgNode pat , string field |
546
- pat = node1 .asPat ( ) and
547
- c = TStructFieldContent ( pat .getStructPat ( ) .getStructField ( field ) ) and
548
- node2 .asPat ( ) = pat .getFieldPat ( field )
549
- )
550
- or
551
- c instanceof ReferenceContent and
552
- node1 .asPat ( ) .( RefPatCfgNode ) .getPat ( ) = node2 .asPat ( )
553
- or
554
- exists ( FieldExprCfgNode access |
555
- node1 .asExpr ( ) = access .getContainer ( ) and
556
- node2 .asExpr ( ) = access and
557
- access = c .( FieldContent ) .getAnAccess ( )
558
- )
559
- or
560
- exists ( IndexExprCfgNode arr |
561
- c instanceof ElementContent and
562
- node1 .asExpr ( ) = arr .getBase ( ) and
563
- node2 .asExpr ( ) = arr
564
- )
565
- or
566
- exists ( ForExprCfgNode for |
567
- c instanceof ElementContent and
568
- node1 .asExpr ( ) = for .getIterable ( ) and
569
- node2 .asPat ( ) = for .getPat ( )
570
- )
571
- or
572
- exists ( SlicePatCfgNode pat |
573
- c instanceof ElementContent and
574
- node1 .asPat ( ) = pat and
575
- node2 .asPat ( ) = pat .getAPat ( )
576
- )
577
- or
578
- exists ( TryExprCfgNode try |
579
- node1 .asExpr ( ) = try .getExpr ( ) and
580
- node2 .asExpr ( ) = try and
581
- c .( TupleFieldContent )
582
- .isVariantField ( [ any ( OptionEnum o ) .getSome ( ) , any ( ResultEnum r ) .getOk ( ) ] , 0 )
583
- )
584
- or
585
- exists ( PrefixExprCfgNode deref |
586
- c instanceof ReferenceContent and
587
- deref .getOperatorName ( ) = "*" and
588
- node1 .asExpr ( ) = deref .getExpr ( ) and
589
- node2 .asExpr ( ) = deref
590
- )
591
- or
592
- // Read from function return
593
- exists ( DataFlowCall call |
594
- lambdaCall ( call , _, node1 ) and
595
- call = node2 .( OutNode ) .getCall ( TNormalReturnKind ( ) ) and
596
- c instanceof FunctionCallReturnContent
597
- )
598
- or
599
- exists ( AwaitExprCfgNode await |
600
- c instanceof FutureContent and
601
- node1 .asExpr ( ) = await .getExpr ( ) and
602
- node2 .asExpr ( ) = await
603
- )
604
- or
605
- referenceExprToExpr ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
606
- node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
607
- or
608
- // Step from receiver expression to receiver node, in case of an implicit
609
- // dereference.
610
- implicitDerefToReceiver ( node1 , node2 , c )
611
- or
612
- // A read step dual to the store step for implicit borrows.
613
- implicitBorrowToReceiver ( node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ,
614
- node1 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
615
- or
616
- VariableCapture:: readStep ( node1 , c , node2 )
620
+ exists ( Content c |
621
+ c = cs .( SingletonContentSet ) .getContent ( ) and
622
+ readContentStep ( node1 , c , node2 )
617
623
)
618
624
or
619
625
FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , cs ,
@@ -652,7 +658,7 @@ module RustDataFlow implements InputSig<Location> {
652
658
}
653
659
654
660
pragma [ nomagic]
655
- private predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
661
+ additional predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
656
662
exists ( CallExprCfgNode call , int pos |
657
663
node1 .asExpr ( ) = call .getArgument ( pragma [ only_bind_into ] ( pos ) ) and
658
664
node2 .asExpr ( ) = call and
0 commit comments