@@ -860,6 +860,17 @@ module RustDataFlow implements InputSig<Location> {
860860 node instanceof Node:: ClosureParameterNode
861861 }
862862
863+ predicate neverSkipInPathGraph ( Node node ) {
864+ node .getCfgNode ( ) = any ( LetStmtCfgNode s ) .getPat ( )
865+ or
866+ node .getCfgNode ( ) = any ( AssignmentExprCfgNode a ) .getLhs ( )
867+ or
868+ exists ( MatchExprCfgNode match |
869+ node .asExpr ( ) = match .getScrutinee ( ) or
870+ node .asExpr ( ) = match .getArmPat ( _)
871+ )
872+ }
873+
863874 class DataFlowExpr = ExprCfgNode ;
864875
865876 /** Gets the node corresponding to `e`. */
@@ -962,8 +973,8 @@ module RustDataFlow implements InputSig<Location> {
962973 /** Holds if path `p` resolves to variant `v`. */
963974 private predicate pathResolveToVariantCanonicalPath ( PathAstNode p , VariantCanonicalPath v ) {
964975 exists ( CrateOriginOption crate , string path , string name |
965- resolveExtendedCanonicalPath ( p , crate , path + "::" + name ) and
966- v = MkVariantCanonicalPath ( crate , path , name )
976+ resolveExtendedCanonicalPath ( p , pragma [ only_bind_into ] ( crate ) , path + "::" + name ) and
977+ v = MkVariantCanonicalPath ( pragma [ only_bind_into ] ( crate ) , path , name )
967978 )
968979 }
969980
@@ -1086,63 +1097,65 @@ module RustDataFlow implements InputSig<Location> {
10861097 )
10871098 }
10881099
1100+ pragma [ nomagic]
1101+ private predicate storeContentStep ( Node node1 , Content c , Node node2 ) {
1102+ exists ( CallExprCfgNode call , int pos |
1103+ tupleVariantConstruction ( call .getCallExpr ( ) ,
1104+ c .( VariantPositionContent ) .getVariantCanonicalPath ( pos ) ) and
1105+ node1 .asExpr ( ) = call .getArgument ( pos ) and
1106+ node2 .asExpr ( ) = call
1107+ )
1108+ or
1109+ exists ( RecordExprCfgNode re , string field |
1110+ (
1111+ // Expression is for a struct-like enum variant.
1112+ recordVariantConstruction ( re .getRecordExpr ( ) ,
1113+ c .( VariantFieldContent ) .getVariantCanonicalPath ( field ) )
1114+ or
1115+ // Expression is for a struct.
1116+ structConstruction ( re .getRecordExpr ( ) , c .( StructFieldContent ) .getStructCanonicalPath ( field ) )
1117+ ) and
1118+ node1 .asExpr ( ) = re .getFieldExpr ( field ) and
1119+ node2 .asExpr ( ) = re
1120+ )
1121+ or
1122+ exists ( TupleExprCfgNode tuple |
1123+ node1 .asExpr ( ) = tuple .getField ( c .( TuplePositionContent ) .getPosition ( ) ) and
1124+ node2 .asExpr ( ) = tuple
1125+ )
1126+ or
1127+ c instanceof ArrayElementContent and
1128+ node1 .asExpr ( ) =
1129+ [
1130+ node2 .asExpr ( ) .( ArrayRepeatExprCfgNode ) .getRepeatOperand ( ) ,
1131+ node2 .asExpr ( ) .( ArrayListExprCfgNode ) .getAnExpr ( )
1132+ ]
1133+ or
1134+ tupleAssignment ( node1 , node2 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
1135+ or
1136+ exists ( AssignmentExprCfgNode assignment , IndexExprCfgNode index |
1137+ c instanceof ArrayElementContent and
1138+ assignment .getLhs ( ) = index and
1139+ node1 .asExpr ( ) = assignment .getRhs ( ) and
1140+ node2 .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = index .getBase ( )
1141+ )
1142+ or
1143+ exists ( RefExprCfgNode ref |
1144+ c instanceof ReferenceContent and
1145+ node1 .asExpr ( ) = ref .getExpr ( ) and
1146+ node2 .asExpr ( ) = ref
1147+ )
1148+ or
1149+ VariableCapture:: storeStep ( node1 , c , node2 )
1150+ }
1151+
10891152 /**
10901153 * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
10911154 * `node2` references an object with a content `c.getAStoreContent()` that
10921155 * contains the value of `node1`.
10931156 */
10941157 predicate storeStep ( Node node1 , ContentSet cs , Node node2 ) {
1095- exists ( Content c | c = cs .( SingletonContentSet ) .getContent ( ) |
1096- exists ( CallExprCfgNode call , int pos |
1097- tupleVariantConstruction ( call .getCallExpr ( ) ,
1098- c .( VariantPositionContent ) .getVariantCanonicalPath ( pos ) ) and
1099- node1 .asExpr ( ) = call .getArgument ( pos ) and
1100- node2 .asExpr ( ) = call
1101- )
1102- or
1103- exists ( RecordExprCfgNode re , string field |
1104- (
1105- // Expression is for a struct-like enum variant.
1106- recordVariantConstruction ( re .getRecordExpr ( ) ,
1107- c .( VariantFieldContent ) .getVariantCanonicalPath ( field ) )
1108- or
1109- // Expression is for a struct.
1110- structConstruction ( re .getRecordExpr ( ) ,
1111- c .( StructFieldContent ) .getStructCanonicalPath ( field ) )
1112- ) and
1113- node1 .asExpr ( ) = re .getFieldExpr ( field ) and
1114- node2 .asExpr ( ) = re
1115- )
1116- or
1117- exists ( TupleExprCfgNode tuple |
1118- node1 .asExpr ( ) = tuple .getField ( c .( TuplePositionContent ) .getPosition ( ) ) and
1119- node2 .asExpr ( ) = tuple
1120- )
1121- or
1122- c instanceof ArrayElementContent and
1123- node1 .asExpr ( ) =
1124- [
1125- node2 .asExpr ( ) .( ArrayRepeatExprCfgNode ) .getRepeatOperand ( ) ,
1126- node2 .asExpr ( ) .( ArrayListExprCfgNode ) .getAnExpr ( )
1127- ]
1128- or
1129- tupleAssignment ( node1 , node2 .( PostUpdateNode ) .getPreUpdateNode ( ) , c )
1130- or
1131- exists ( AssignmentExprCfgNode assignment , IndexExprCfgNode index |
1132- c instanceof ArrayElementContent and
1133- assignment .getLhs ( ) = index and
1134- node1 .asExpr ( ) = assignment .getRhs ( ) and
1135- node2 .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = index .getBase ( )
1136- )
1137- or
1138- exists ( RefExprCfgNode ref |
1139- c instanceof ReferenceContent and
1140- node1 .asExpr ( ) = ref .getExpr ( ) and
1141- node2 .asExpr ( ) = ref
1142- )
1143- or
1144- VariableCapture:: storeStep ( node1 , c , node2 )
1145- )
1158+ storeContentStep ( node1 , cs .( SingletonContentSet ) .getContent ( ) , node2 )
11461159 or
11471160 FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( Node:: FlowSummaryNode ) .getSummaryNode ( ) ,
11481161 cs , node2 .( Node:: FlowSummaryNode ) .getSummaryNode ( ) )
0 commit comments