Skip to content

Commit 623f6ff

Browse files
committed
C++: Move things around so that 'getAdditionalFlowIntoCallNodeTerm' is in the same stage as 'DataFlowImplCommon'.
1 parent deb43c2 commit 623f6ff

File tree

1 file changed

+50
-42
lines changed

1 file changed

+50
-42
lines changed

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

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,59 @@ private import DataFlowDispatch
55
private import DataFlowImplConsistency
66
private import semmle.code.cpp.ir.internal.IRCppLanguage
77
private import SsaInternals as Ssa
8-
private import DataFlowImplCommon
8+
private import DataFlowImplCommon as DataFlowImplCommon
99
private import semmle.code.cpp.ir.ValueNumbering
1010

1111
cached
1212
private module Cached {
1313
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
3561

3662
class Node0Impl extends TIRDataFlowNode0 {
3763
/**
@@ -906,7 +932,7 @@ private predicate localFlowStepWithSummaries(Node node1, Node node2) {
906932
or
907933
readStep(node1, _, node2)
908934
or
909-
argumentValueFlowsThrough(node1, _, node2)
935+
DataFlowImplCommon::argumentValueFlowsThrough(node1, _, node2)
910936
}
911937

912938
/** Holds if `node` flows to a node that is used in a `SwitchInstruction`. */
@@ -946,24 +972,6 @@ private predicate getAdditionalFlowIntoCallNodeTermStep(Node node1, Node node2)
946972
localFlowStepWithSummaries(node1, node2)
947973
}
948974

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-
967975
/** Gets the `IRVariable` associated with the parameter node `p`. */
968976
pragma[nomagic]
969977
private IRVariable getIRVariableForParameterNode(ParameterNode p) {
@@ -992,7 +1000,7 @@ private EdgeKind caseOrDefaultEdge() {
9921000
/**
9931001
* Gets the number of switch branches that that read from (or write to) the parameter `p`.
9941002
*/
995-
int countNumberOfBranchesUsingParameter(SwitchInstruction switch, ParameterNode p) {
1003+
private int countNumberOfBranchesUsingParameter(SwitchInstruction switch, ParameterNode p) {
9961004
exists(Ssa::SourceVariable sv |
9971005
parameterNodeHasSourceVariable(p, sv) and
9981006
// Count the number of cases that use the parameter. We do this by finding the phi node

0 commit comments

Comments
 (0)