Skip to content

Commit c45127f

Browse files
authored
Merge pull request #7541 from github/rdmarsh2/dataflow-ipa-params
C++: Use an IPA type rather than negative indexes for argument/parameter matching in data flow
2 parents 7b0d9ea + 6733997 commit c45127f

File tree

3 files changed

+62
-35
lines changed

3 files changed

+62
-35
lines changed

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private module VirtualDispatch {
6363
this.flowsFrom(other, allowOtherFromArg)
6464
|
6565
// Call argument
66-
exists(DataFlowCall call, int i |
66+
exists(DataFlowCall call, Position i |
6767
other
6868
.(DataFlow::ParameterNode)
6969
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
@@ -268,16 +268,6 @@ Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
268268
)
269269
}
270270

271-
/** A parameter position represented by an integer. */
272-
class ParameterPosition extends int {
273-
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
274-
}
275-
276-
/** An argument position represented by an integer. */
277-
class ArgumentPosition extends int {
278-
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
279-
}
280-
281271
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
282272
pragma[inline]
283273
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

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

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ abstract class ArgumentNode extends OperandNode {
2727
* Holds if this argument occurs at the given position in the given call.
2828
* The instance argument is considered to have index `-1`.
2929
*/
30-
abstract predicate argumentOf(DataFlowCall call, int pos);
30+
abstract predicate argumentOf(DataFlowCall call, ArgumentPosition pos);
3131

3232
/** Gets the call in which this node is an argument. */
3333
DataFlowCall getCall() { this.argumentOf(result, _) }
@@ -42,7 +42,9 @@ private class PrimaryArgumentNode extends ArgumentNode {
4242

4343
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
4444

45-
override predicate argumentOf(DataFlowCall call, int pos) { op = call.getArgumentOperand(pos) }
45+
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
46+
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
47+
}
4648

4749
override string toString() {
4850
exists(Expr unconverted |
@@ -71,9 +73,9 @@ private class SideEffectArgumentNode extends ArgumentNode {
7173

7274
SideEffectArgumentNode() { op = read.getSideEffectOperand() }
7375

74-
override predicate argumentOf(DataFlowCall call, int pos) {
76+
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
7577
read.getPrimaryInstruction() = call and
76-
pos = getArgumentPosOfSideEffect(read.getIndex())
78+
pos.(IndirectionPosition).getIndex() = read.getIndex()
7779
}
7880

7981
override string toString() {
@@ -90,6 +92,54 @@ private class SideEffectArgumentNode extends ArgumentNode {
9092
}
9193
}
9294

95+
/** A parameter position represented by an integer. */
96+
class ParameterPosition = Position;
97+
98+
/** An argument position represented by an integer. */
99+
class ArgumentPosition = Position;
100+
101+
class Position extends TPosition {
102+
abstract string toString();
103+
}
104+
105+
class DirectPosition extends TDirectPosition {
106+
int index;
107+
108+
DirectPosition() { this = TDirectPosition(index) }
109+
110+
string toString() {
111+
index = -1 and
112+
result = "this"
113+
or
114+
index != -1 and
115+
result = index.toString()
116+
}
117+
118+
int getIndex() { result = index }
119+
}
120+
121+
class IndirectionPosition extends TIndirectionPosition {
122+
int index;
123+
124+
IndirectionPosition() { this = TIndirectionPosition(index) }
125+
126+
string toString() {
127+
index = -1 and
128+
result = "this"
129+
or
130+
index != -1 and
131+
result = index.toString()
132+
}
133+
134+
int getIndex() { result = index }
135+
}
136+
137+
newtype TPosition =
138+
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
139+
TIndirectionPosition(int index) {
140+
exists(ReadSideEffectInstruction instr | instr.getIndex() = index)
141+
}
142+
93143
private newtype TReturnKind =
94144
TNormalReturnKind() or
95145
TIndirectReturnKind(ParameterIndex index)

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -490,19 +490,6 @@ class ExprNode extends InstructionNode {
490490
override string toString() { result = this.asConvertedExpr().toString() }
491491
}
492492

493-
/**
494-
* INTERNAL: do not use. Translates a parameter/argument index into a negative
495-
* number that denotes the index of its side effect (pointer indirection).
496-
*/
497-
bindingset[index]
498-
int getArgumentPosOfSideEffect(int index) {
499-
// -1 -> -2
500-
// 0 -> -3
501-
// 1 -> -4
502-
// ...
503-
result = -3 - index
504-
}
505-
506493
/**
507494
* The value of a parameter at function entry, viewed as a node in a data
508495
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -525,7 +512,7 @@ class ParameterNode extends InstructionNode {
525512
* implicit `this` parameter is considered to have position `-1`, and
526513
* pointer-indirection parameters are at further negative positions.
527514
*/
528-
predicate isParameterOf(Function f, int pos) { none() } // overridden by subclasses
515+
predicate isParameterOf(Function f, ParameterPosition pos) { none() } // overridden by subclasses
529516
}
530517

531518
/** An explicit positional parameter, not including `this` or `...`. */
@@ -534,8 +521,8 @@ private class ExplicitParameterNode extends ParameterNode {
534521

535522
ExplicitParameterNode() { exists(instr.getParameter()) }
536523

537-
override predicate isParameterOf(Function f, int pos) {
538-
f.getParameter(pos) = instr.getParameter()
524+
override predicate isParameterOf(Function f, ParameterPosition pos) {
525+
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
539526
}
540527

541528
/** Gets the `Parameter` associated with this node. */
@@ -550,8 +537,8 @@ class ThisParameterNode extends ParameterNode {
550537

551538
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
552539

553-
override predicate isParameterOf(Function f, int pos) {
554-
pos = -1 and instr.getEnclosingFunction() = f
540+
override predicate isParameterOf(Function f, ParameterPosition pos) {
541+
pos.(DirectPosition).getIndex() = -1 and instr.getEnclosingFunction() = f
555542
}
556543

557544
override string toString() { result = "this" }
@@ -561,12 +548,12 @@ class ThisParameterNode extends ParameterNode {
561548
class ParameterIndirectionNode extends ParameterNode {
562549
override InitializeIndirectionInstruction instr;
563550

564-
override predicate isParameterOf(Function f, int pos) {
551+
override predicate isParameterOf(Function f, ParameterPosition pos) {
565552
exists(int index |
566553
instr.getEnclosingFunction() = f and
567554
instr.hasIndex(index)
568555
|
569-
pos = getArgumentPosOfSideEffect(index)
556+
pos.(IndirectionPosition).getIndex() = index
570557
)
571558
}
572559

0 commit comments

Comments
 (0)