@@ -523,97 +523,103 @@ module RustDataFlow implements InputSig<Location> {
523523 exists ( c )
524524 }
525525
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+
526614 /**
527615 * Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
528616 * `node1` references an object with a content `c.getAReadContent()` whose
529617 * value ends up in `node2`.
530618 */
531619 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 )
617623 )
618624 or
619625 FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , cs ,
@@ -652,7 +658,7 @@ module RustDataFlow implements InputSig<Location> {
652658 }
653659
654660 pragma [ nomagic]
655- private predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
661+ additional predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
656662 exists ( CallExprCfgNode call , int pos |
657663 node1 .asExpr ( ) = call .getArgument ( pragma [ only_bind_into ] ( pos ) ) and
658664 node2 .asExpr ( ) = call and
0 commit comments