@@ -897,6 +897,55 @@ IRBlock getBasicBlock(Node node) {
897
897
result = getBasicBlock ( node .( PostUpdateNode ) .getPreUpdateNode ( ) )
898
898
}
899
899
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
+
900
949
/**
901
950
* Gets an additional term that is added to the `join` and `branch` computations to reflect
902
951
* an additional forward or backwards branching factor that is not taken into account
@@ -910,7 +959,7 @@ int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p) {
910
959
viableParamArg ( call , p , arg ) and
911
960
viableParamArg ( call , switchee , _) and
912
961
switch .getExpressionOperand ( ) = op and
913
- valueNumber ( switchee . asInstruction ( ) ) . getAUse ( ) = op and
962
+ getAdditionalFlowIntoCallNodeTermStep + ( switchee , operandNode ( op ) ) and
914
963
result = countNumberOfBranchesUsingParameter ( switch , p )
915
964
)
916
965
}
0 commit comments