@@ -5,33 +5,59 @@ private import DataFlowDispatch
5
5
private import DataFlowImplConsistency
6
6
private import semmle.code.cpp.ir.internal.IRCppLanguage
7
7
private import SsaInternals as Ssa
8
- private import DataFlowImplCommon
8
+ private import DataFlowImplCommon as DataFlowImplCommon
9
9
private import semmle.code.cpp.ir.ValueNumbering
10
10
11
11
cached
12
12
private module Cached {
13
13
cached
14
- newtype TIRDataFlowNode0 =
15
- TInstructionNode0 ( Instruction i ) {
16
- not Ssa:: ignoreInstruction ( i ) and
17
- not exists ( Operand op |
18
- not Ssa:: ignoreOperand ( op ) and i = Ssa:: getIRRepresentationOfOperand ( op )
19
- ) and
20
- // We exclude `void`-typed instructions because they cannot contain data.
21
- // However, if the instruction is a glvalue, and their type is `void`, then the result
22
- // type of the instruction is really `void*`, and thus we still want to have a dataflow
23
- // node for it.
24
- ( not i .getResultType ( ) instanceof VoidType or i .isGLValue ( ) )
25
- } or
26
- TMultipleUseOperandNode0 ( Operand op ) {
27
- not Ssa:: ignoreOperand ( op ) and not exists ( Ssa:: getIRRepresentationOfOperand ( op ) )
28
- } or
29
- TSingleUseOperandNode0 ( Operand op ) {
30
- not Ssa:: ignoreOperand ( op ) and exists ( Ssa:: getIRRepresentationOfOperand ( op ) )
31
- }
32
- }
33
-
34
- private import Cached
14
+ module Nodes0 {
15
+ cached
16
+ newtype TIRDataFlowNode0 =
17
+ TInstructionNode0 ( Instruction i ) {
18
+ not Ssa:: ignoreInstruction ( i ) and
19
+ not exists ( Operand op |
20
+ not Ssa:: ignoreOperand ( op ) and i = Ssa:: getIRRepresentationOfOperand ( op )
21
+ ) and
22
+ // We exclude `void`-typed instructions because they cannot contain data.
23
+ // However, if the instruction is a glvalue, and their type is `void`, then the result
24
+ // type of the instruction is really `void*`, and thus we still want to have a dataflow
25
+ // node for it.
26
+ ( not i .getResultType ( ) instanceof VoidType or i .isGLValue ( ) )
27
+ } or
28
+ TMultipleUseOperandNode0 ( Operand op ) {
29
+ not Ssa:: ignoreOperand ( op ) and not exists ( Ssa:: getIRRepresentationOfOperand ( op ) )
30
+ } or
31
+ TSingleUseOperandNode0 ( Operand op ) {
32
+ not Ssa:: ignoreOperand ( op ) and exists ( Ssa:: getIRRepresentationOfOperand ( op ) )
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Gets an additional term that is added to the `join` and `branch` computations to reflect
38
+ * an additional forward or backwards branching factor that is not taken into account
39
+ * when calculating the (virtual) dispatch cost.
40
+ *
41
+ * Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
42
+ */
43
+ pragma [ nomagic]
44
+ cached
45
+ int getAdditionalFlowIntoCallNodeTerm ( ArgumentNode arg , ParameterNode p ) {
46
+ DataFlowImplCommon:: forceCachingInSameStage ( ) and
47
+ exists (
48
+ ParameterNode switchee , SwitchInstruction switch , ConditionOperand op , DataFlowCall call
49
+ |
50
+ DataFlowImplCommon:: viableParamArg ( call , p , arg ) and
51
+ DataFlowImplCommon:: viableParamArg ( call , switchee , _) and
52
+ switch .getExpressionOperand ( ) = op and
53
+ getAdditionalFlowIntoCallNodeTermStep + ( switchee , operandNode ( op ) ) and
54
+ result = countNumberOfBranchesUsingParameter ( switch , p )
55
+ )
56
+ }
57
+ }
58
+
59
+ import Cached
60
+ private import Nodes0
35
61
36
62
class Node0Impl extends TIRDataFlowNode0 {
37
63
/**
@@ -906,7 +932,7 @@ private predicate localFlowStepWithSummaries(Node node1, Node node2) {
906
932
or
907
933
readStep ( node1 , _, node2 )
908
934
or
909
- argumentValueFlowsThrough ( node1 , _, node2 )
935
+ DataFlowImplCommon :: argumentValueFlowsThrough ( node1 , _, node2 )
910
936
}
911
937
912
938
/** Holds if `node` flows to a node that is used in a `SwitchInstruction`. */
@@ -946,24 +972,6 @@ private predicate getAdditionalFlowIntoCallNodeTermStep(Node node1, Node node2)
946
972
localFlowStepWithSummaries ( node1 , node2 )
947
973
}
948
974
949
- /**
950
- * Gets an additional term that is added to the `join` and `branch` computations to reflect
951
- * an additional forward or backwards branching factor that is not taken into account
952
- * when calculating the (virtual) dispatch cost.
953
- *
954
- * Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
955
- */
956
- pragma [ nomagic]
957
- int getAdditionalFlowIntoCallNodeTerm ( ArgumentNode arg , ParameterNode p ) {
958
- exists ( ParameterNode switchee , SwitchInstruction switch , ConditionOperand op , DataFlowCall call |
959
- viableParamArg ( call , p , arg ) and
960
- viableParamArg ( call , switchee , _) and
961
- switch .getExpressionOperand ( ) = op and
962
- getAdditionalFlowIntoCallNodeTermStep + ( switchee , operandNode ( op ) ) and
963
- result = countNumberOfBranchesUsingParameter ( switch , p )
964
- )
965
- }
966
-
967
975
/** Gets the `IRVariable` associated with the parameter node `p`. */
968
976
pragma [ nomagic]
969
977
private IRVariable getIRVariableForParameterNode ( ParameterNode p ) {
@@ -992,7 +1000,7 @@ private EdgeKind caseOrDefaultEdge() {
992
1000
/**
993
1001
* Gets the number of switch branches that that read from (or write to) the parameter `p`.
994
1002
*/
995
- int countNumberOfBranchesUsingParameter ( SwitchInstruction switch , ParameterNode p ) {
1003
+ private int countNumberOfBranchesUsingParameter ( SwitchInstruction switch , ParameterNode p ) {
996
1004
exists ( Ssa:: SourceVariable sv |
997
1005
parameterNodeHasSourceVariable ( p , sv ) and
998
1006
// Count the number of cases that use the parameter. We do this by finding the phi node
0 commit comments