Skip to content

Commit aabcc10

Browse files
committed
Rust: Fix bad join
``` [2024-12-16 10:10:36] (247s) Tuple counts for DataFlowImpl::RustDataFlow::storeStep/3#98e80e57/3@0618fdm6 after 3m8s: 33711 ~0% {3} r1 = SCAN `DataFlowImpl::VariableCapture::storeStep/3#cb0fdcf6` OUTPUT In.1, In.0 'node1', In.2 'node2' 33711 ~6% {3} | JOIN WITH DataFlowImpl::TSingletonContentSet#9b15eaba ON FIRST 1 OUTPUT Lhs.1 'node1', Rhs.1 'cs', Lhs.2 'node2' 0 ~0% {3} r2 = JOIN `FlowSummaryImpl::Private::Steps::summaryStoreStep/3#2c853d0d` WITH DataFlowImpl::TFlowSummaryNode#2b28ecb7 ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'cs', Rhs.1 'node1' 0 ~0% {3} | JOIN WITH DataFlowImpl::TFlowSummaryNode#2b28ecb7 ON FIRST 1 OUTPUT Lhs.2 'node1', Lhs.1 'cs', Rhs.1 'node1' 1554 ~0% {3} r3 = JOIN _DataFlowImpl::TExprNode#83a34c2e__DataFlowImpl::TArrayElement#b9fb9b7b_DataFlowImpl::TSingletonCont__#shared WITH `CfgNodes::ArrayRepeatExprCfgNode.getRepeatOperand/0#dispred#b264e402_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 'node1' 1554 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Lhs.2 'node1', Lhs.1 'cs', Rhs.1 'node2' 870 ~2% {3} r4 = SCAN `DataFlowImpl::RustDataFlow::tupleAssignment/3#bf3c8690` OUTPUT In.2, In.0 'node1', In.1 870 ~0% {3} | JOIN WITH DataFlowImpl::TSingletonContentSet#9b15eaba ON FIRST 1 OUTPUT Lhs.2, Rhs.1 'cs', Lhs.1 'node1' 870 ~0% {3} | JOIN WITH `DataFlowImpl::Node::PostUpdateNode.getPreUpdateNode/0#dispred#53daedc2_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2 'node1', Lhs.1 'cs', Rhs.1 'node2' 40037 ~4% {3} r5 = JOIN _DataFlowImpl::TExprNode#83a34c2e__DataFlowImpl::TArrayElement#b9fb9b7b_DataFlowImpl::TSingletonCont__#shared WITH `CfgNodes::ArrayExprCfgNode.getAnExpr/0#dispred#9d00a6f1_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 'node1' 36929 ~4% {3} | JOIN WITH CfgNodes::ArrayListExprCfgNode#07eee614 ON FIRST 1 OUTPUT Lhs.0, Lhs.1 'cs', Lhs.2 'node1' 36929 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Lhs.2 'node1', Lhs.1 'cs', Rhs.1 'node2' 14 ~0% {2} r6 = JOIN DataFlowImpl::TTuplePositionContent#f1d90606_10#join_rhs WITH DataFlowImpl::TSingletonContentSet#9b15eaba ON FIRST 1 OUTPUT Lhs.1, Rhs.1 'cs' 47949 ~0% {3} | JOIN WITH `CfgNodes::TupleExprCfgNode.getField/1#dispred#9f7c9c63_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Rhs.2 47949 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'cs', Rhs.1 'node2' 47949 ~2% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Rhs.1 'node2', Lhs.1 'cs', Lhs.2 'node2' 59801 ~0% {3} r7 = JOIN _DataFlowImpl::TSingletonContentSet#9b15eaba_DataFlowImpl::TVariantPositionContent#ca6baca0_201#join__#shared WITH `DataFlowImpl::RustDataFlow::tupleVariantConstruction/2#10613c55_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 45509 ~0% {3} | JOIN WITH CfgNodes::CallExprCfgNode#9c2a4686_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 45509 ~2% {4} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Lhs.0, Lhs.2, Lhs.1 'cs', Rhs.1 'node2' 45509 ~0% {3} | JOIN WITH `CfgNodes::CallExprBaseCfgNode.getArgument/1#dispred#9ebb27c0` ON FIRST 2 OUTPUT Rhs.2, Lhs.2 'cs', Lhs.3 'node2' 45509 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Rhs.1 'node2', Lhs.1 'cs', Lhs.2 'node2' 75147 ~1% {3} r8 = JOIN _DataFlowImpl::TSingletonContentSet#9b15eaba_DataFlowImpl::TStructFieldContent#1d6d7b05_201#join_rhs#shared WITH `DataFlowImpl::RustDataFlow::structConstruction/2#a9656db0_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 59186 ~3% {3} | JOIN WITH `CfgNodes::RecordExprCfgNode.getRecordExpr/0#dispred#659ad1af_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 5641 ~2% {3} r9 = JOIN _DataFlowImpl::TSingletonContentSet#9b15eaba_DataFlowImpl::TVariantFieldContent#4e05bcf1_201#join_rh__#shared WITH `DataFlowImpl::RustDataFlow::recordVariantConstruction/2#34b016f6_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 5268 ~0% {3} | JOIN WITH `CfgNodes::RecordExprCfgNode.getRecordExpr/0#dispred#659ad1af_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 64454 ~1% {3} r10 = r8 UNION r9 64454 ~0% {4} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Lhs.0, Lhs.2, Lhs.1 'cs', Rhs.1 'node2' 25923 ~0% {3} | JOIN WITH `CfgNodes::RecordExprCfgNode.getFieldExpr/1#d72dca6e` ON FIRST 2 OUTPUT Rhs.2, Lhs.2 'cs', Lhs.3 'node2' 25923 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Rhs.1 'node2', Lhs.1 'cs', Lhs.2 'node2' 67759289500 ~251% {4} r11 = JOIN DataFlowImpl::TSingletonContentSet#9b15eaba WITH DataFlowImpl::TExprNode#83a34c2e CARTESIAN PRODUCT OUTPUT Lhs.0, Lhs.1 'cs', Rhs.0, Rhs.1 'node2' 3568000 ~1488% {3} | JOIN WITH DataFlowImpl::TArrayElement#b9fb9b7b ON FIRST 1 OUTPUT Lhs.3, Lhs.1 'cs', Lhs.2 1223000 ~1291% {3} | JOIN WITH `DataFlowImpl::Node::PostUpdateNode.getPreUpdateNode/0#dispred#53daedc2_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'cs', Rhs.1 'node2' 11500 ~0% {3} | JOIN WITH `CfgNodes::IndexExprCfgNode.getBase/0#dispred#19aba7d8_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 'node2' 1000 ~3% {3} | JOIN WITH `CfgNodes::BinaryExprCfgNode.getLhs/0#dispred#bd1c02e7_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 'node2' 500 ~3% {3} | JOIN WITH CfgNodes::AssignmentExprCfgNode#a9a5c022 ON FIRST 1 OUTPUT Lhs.0, Lhs.1 'cs', Lhs.2 'node2' 0 ~0% {3} | JOIN WITH `CfgNodes::BinaryExprCfgNode.getRhs/0#dispred#4a1146e4` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'cs', Lhs.2 'node2' 0 ~0% {3} | JOIN WITH DataFlowImpl::TExprNode#83a34c2e ON FIRST 1 OUTPUT Rhs.1 'node2', Lhs.1 'cs', Lhs.2 'node2' 192445 ~1% {3} r12 = r1 UNION r2 UNION r3 UNION r4 UNION r5 UNION r6 UNION r7 UNION r10 UNION r11 return r12 ```
1 parent 2d16b52 commit aabcc10

File tree

1 file changed

+47
-45
lines changed

1 file changed

+47
-45
lines changed

rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,57 +1074,59 @@ module RustDataFlow implements InputSig<Location> {
10741074
)
10751075
}
10761076

1077+
pragma[nomagic]
1078+
private predicate storeContentStep(Node node1, Content c, Node node2) {
1079+
exists(CallExprCfgNode call, int pos |
1080+
tupleVariantConstruction(call.getCallExpr(),
1081+
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
1082+
node1.asExpr() = call.getArgument(pos) and
1083+
node2.asExpr() = call
1084+
)
1085+
or
1086+
exists(RecordExprCfgNode re, string field |
1087+
(
1088+
// Expression is for a struct-like enum variant.
1089+
recordVariantConstruction(re.getRecordExpr(),
1090+
c.(VariantFieldContent).getVariantCanonicalPath(field))
1091+
or
1092+
// Expression is for a struct.
1093+
structConstruction(re.getRecordExpr(), c.(StructFieldContent).getStructCanonicalPath(field))
1094+
) and
1095+
node1.asExpr() = re.getFieldExpr(field) and
1096+
node2.asExpr() = re
1097+
)
1098+
or
1099+
exists(TupleExprCfgNode tuple |
1100+
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
1101+
node2.asExpr() = tuple
1102+
)
1103+
or
1104+
c instanceof ArrayElementContent and
1105+
node1.asExpr() =
1106+
[
1107+
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
1108+
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
1109+
]
1110+
or
1111+
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
1112+
or
1113+
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
1114+
c instanceof ArrayElementContent and
1115+
assignment.getLhs() = index and
1116+
node1.asExpr() = assignment.getRhs() and
1117+
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
1118+
)
1119+
or
1120+
VariableCapture::storeStep(node1, c, node2)
1121+
}
1122+
10771123
/**
10781124
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
10791125
* `node2` references an object with a content `c.getAStoreContent()` that
10801126
* contains the value of `node1`.
10811127
*/
10821128
predicate storeStep(Node node1, ContentSet cs, Node node2) {
1083-
exists(Content c | c = cs.(SingletonContentSet).getContent() |
1084-
exists(CallExprCfgNode call, int pos |
1085-
tupleVariantConstruction(call.getCallExpr(),
1086-
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
1087-
node1.asExpr() = call.getArgument(pos) and
1088-
node2.asExpr() = call
1089-
)
1090-
or
1091-
exists(RecordExprCfgNode re, string field |
1092-
(
1093-
// Expression is for a struct-like enum variant.
1094-
recordVariantConstruction(re.getRecordExpr(),
1095-
c.(VariantFieldContent).getVariantCanonicalPath(field))
1096-
or
1097-
// Expression is for a struct.
1098-
structConstruction(re.getRecordExpr(),
1099-
c.(StructFieldContent).getStructCanonicalPath(field))
1100-
) and
1101-
node1.asExpr() = re.getFieldExpr(field) and
1102-
node2.asExpr() = re
1103-
)
1104-
or
1105-
exists(TupleExprCfgNode tuple |
1106-
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
1107-
node2.asExpr() = tuple
1108-
)
1109-
or
1110-
c instanceof ArrayElementContent and
1111-
node1.asExpr() =
1112-
[
1113-
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
1114-
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
1115-
]
1116-
or
1117-
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
1118-
or
1119-
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
1120-
c instanceof ArrayElementContent and
1121-
assignment.getLhs() = index and
1122-
node1.asExpr() = assignment.getRhs() and
1123-
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
1124-
)
1125-
or
1126-
VariableCapture::storeStep(node1, c, node2)
1127-
)
1129+
storeContentStep(node1, cs.(SingletonContentSet).getContent(), node2)
11281130
or
11291131
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
11301132
cs, node2.(Node::FlowSummaryNode).getSummaryNode())

0 commit comments

Comments
 (0)