@@ -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