@@ -860,6 +860,17 @@ module RustDataFlow implements InputSig<Location> {
860
860
node instanceof Node:: ClosureParameterNode
861
861
}
862
862
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
+
863
874
class DataFlowExpr = ExprCfgNode ;
864
875
865
876
/** Gets the node corresponding to `e`. */
@@ -962,8 +973,8 @@ module RustDataFlow implements InputSig<Location> {
962
973
/** Holds if path `p` resolves to variant `v`. */
963
974
private predicate pathResolveToVariantCanonicalPath ( PathAstNode p , VariantCanonicalPath v ) {
964
975
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 )
967
978
)
968
979
}
969
980
@@ -1086,63 +1097,65 @@ module RustDataFlow implements InputSig<Location> {
1086
1097
)
1087
1098
}
1088
1099
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
+
1089
1152
/**
1090
1153
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
1091
1154
* `node2` references an object with a content `c.getAStoreContent()` that
1092
1155
* contains the value of `node1`.
1093
1156
*/
1094
1157
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 )
1146
1159
or
1147
1160
FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( Node:: FlowSummaryNode ) .getSummaryNode ( ) ,
1148
1161
cs , node2 .( Node:: FlowSummaryNode ) .getSummaryNode ( ) )
0 commit comments