Skip to content

Commit deb43c2

Browse files
committed
C++: Use local flow instead of GVN to find parameters that are used in switch statements.
1 parent d96dbea commit deb43c2

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,55 @@ IRBlock getBasicBlock(Node node) {
897897
result = getBasicBlock(node.(PostUpdateNode).getPreUpdateNode())
898898
}
899899

900+
/**
901+
* A local flow relation that includes both local steps, read steps and
902+
* argument-to-return flow through summarized functions.
903+
*/
904+
private predicate localFlowStepWithSummaries(Node node1, Node node2) {
905+
localFlowStep(node1, node2)
906+
or
907+
readStep(node1, _, node2)
908+
or
909+
argumentValueFlowsThrough(node1, _, node2)
910+
}
911+
912+
/** Holds if `node` flows to a node that is used in a `SwitchInstruction`. */
913+
private predicate localStepsToSwitch(Node node) {
914+
node.asOperand() = any(SwitchInstruction switch).getExpressionOperand()
915+
or
916+
exists(Node succ |
917+
localStepsToSwitch(succ) and
918+
localFlowStepWithSummaries(node, succ)
919+
)
920+
}
921+
922+
/**
923+
* Holds if `node` is part of a path from a `ParameterNode` to an operand
924+
* of a `SwitchInstruction`.
925+
*/
926+
private predicate localStepsFromParameter(Node node) {
927+
localStepsToSwitch(node) and
928+
(
929+
node instanceof ParameterNode
930+
or
931+
exists(Node prev |
932+
localStepsFromParameter(prev) and
933+
localFlowStepWithSummaries(prev, node)
934+
)
935+
)
936+
}
937+
938+
/**
939+
* The local flow relation `localFlowStepWithSummaries` pruned to only
940+
* include steps that are part of a path from a `ParameterNode` to an
941+
* operand of a `SwitchInstruction`.
942+
*/
943+
private predicate getAdditionalFlowIntoCallNodeTermStep(Node node1, Node node2) {
944+
localStepsFromParameter(node1) and
945+
localStepsFromParameter(node2) and
946+
localFlowStepWithSummaries(node1, node2)
947+
}
948+
900949
/**
901950
* Gets an additional term that is added to the `join` and `branch` computations to reflect
902951
* an additional forward or backwards branching factor that is not taken into account
@@ -910,7 +959,7 @@ int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p) {
910959
viableParamArg(call, p, arg) and
911960
viableParamArg(call, switchee, _) and
912961
switch.getExpressionOperand() = op and
913-
valueNumber(switchee.asInstruction()).getAUse() = op and
962+
getAdditionalFlowIntoCallNodeTermStep+(switchee, operandNode(op)) and
914963
result = countNumberOfBranchesUsingParameter(switch, p)
915964
)
916965
}

0 commit comments

Comments
 (0)