Skip to content

Commit 1890a14

Browse files
committed
C++: IPA for pointer arg instead of negative index
This takes advantage of the new ArgumentPosition and ParameterPosition types in the shared DataFlow library interface to represent indirections with an IPA type rather than the negative-index system in use previously
1 parent d5682f1 commit 1890a14

File tree

3 files changed

+72
-33
lines changed

3 files changed

+72
-33
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: 14 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,12 @@ 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.(Positional).getIndex())
47+
or
48+
op = call.getArgumentOperand(-1) and
49+
pos instanceof ThisPosition
50+
}
4651

4752
override string toString() {
4853
exists(Expr unconverted |
@@ -71,9 +76,14 @@ private class SideEffectArgumentNode extends ArgumentNode {
7176

7277
SideEffectArgumentNode() { op = read.getSideEffectOperand() }
7378

74-
override predicate argumentOf(DataFlowCall call, int pos) {
79+
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
7580
read.getPrimaryInstruction() = call and
76-
pos = getArgumentPosOfSideEffect(read.getIndex())
81+
(
82+
pos.(PositionalIndirection).getIndex() = read.getIndex()
83+
or
84+
pos instanceof ThisIndirectionPosition and
85+
read.getIndex() = -1
86+
)
7787
}
7888

7989
override string toString() {

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

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import semmle.code.cpp.ir.IR
1111
private import semmle.code.cpp.controlflow.IRGuards
1212
private import semmle.code.cpp.models.interfaces.DataFlow
1313
private import DataFlowPrivate
14+
private import DataFlowDispatch
1415
private import SsaInternals as Ssa
1516

1617
cached
@@ -490,19 +491,53 @@ class ExprNode extends InstructionNode {
490491
override string toString() { result = this.asConvertedExpr().toString() }
491492
}
492493

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
494+
/** A parameter position represented by an integer. */
495+
class ParameterPosition = Position;
496+
497+
/** An argument position represented by an integer. */
498+
class ArgumentPosition = Position;
499+
500+
class Position extends TPosition {
501+
abstract string toString();
502+
}
503+
504+
class ThisPosition extends TThisPosition {
505+
string toString() { result = "this" }
506+
}
507+
508+
class ThisIndirectionPosition extends TThisIndirectionPosition {
509+
string toString() { result = "this" }
510+
}
511+
512+
class Positional extends TPositional {
513+
int index;
514+
515+
Positional() { this = TPositional(index) }
516+
517+
string toString() { result = index.toString() }
518+
519+
int getIndex() {
520+
result = index
521+
}
504522
}
505523

524+
class PositionalIndirection extends TPositionalIndirection {
525+
int index;
526+
527+
PositionalIndirection() { this = TPositionalIndirection(index) }
528+
529+
string toString() { result = index.toString() }
530+
int getIndex() {
531+
result = index
532+
}
533+
}
534+
535+
newtype TPosition =
536+
TThisPosition() or
537+
TThisIndirectionPosition() or
538+
TPositional(int index) { exists(any(Call c).getArgument(index)) } or
539+
TPositionalIndirection(int index) { exists(any(Call c).getArgument(index)) }
540+
506541
/**
507542
* The value of a parameter at function entry, viewed as a node in a data
508543
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -525,7 +560,7 @@ class ParameterNode extends InstructionNode {
525560
* implicit `this` parameter is considered to have position `-1`, and
526561
* pointer-indirection parameters are at further negative positions.
527562
*/
528-
predicate isParameterOf(Function f, int pos) { none() } // overridden by subclasses
563+
predicate isParameterOf(Function f, ParameterPosition pos) { none() } // overridden by subclasses
529564
}
530565

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

535570
ExplicitParameterNode() { exists(instr.getParameter()) }
536571

537-
override predicate isParameterOf(Function f, int pos) {
538-
f.getParameter(pos) = instr.getParameter()
572+
override predicate isParameterOf(Function f, ParameterPosition pos) {
573+
f.getParameter(pos.(Positional).getIndex()) = instr.getParameter()
539574
}
540575

541576
/** Gets the `Parameter` associated with this node. */
@@ -550,8 +585,8 @@ class ThisParameterNode extends ParameterNode {
550585

551586
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
552587

553-
override predicate isParameterOf(Function f, int pos) {
554-
pos = -1 and instr.getEnclosingFunction() = f
588+
override predicate isParameterOf(Function f, ParameterPosition pos) {
589+
pos instanceof ThisPosition and instr.getEnclosingFunction() = f
555590
}
556591

557592
override string toString() { result = "this" }
@@ -561,13 +596,17 @@ class ThisParameterNode extends ParameterNode {
561596
class ParameterIndirectionNode extends ParameterNode {
562597
override InitializeIndirectionInstruction instr;
563598

564-
override predicate isParameterOf(Function f, int pos) {
599+
override predicate isParameterOf(Function f, ParameterPosition pos) {
565600
exists(int index |
566601
instr.getEnclosingFunction() = f and
567602
instr.hasIndex(index)
568603
|
569-
pos = getArgumentPosOfSideEffect(index)
604+
pos.(PositionalIndirection).getIndex() = index
570605
)
606+
or
607+
instr.getEnclosingFunction() = f and
608+
instr.hasIndex(-1) and
609+
pos instanceof ThisIndirectionPosition
571610
}
572611

573612
override string toString() { result = "*" + instr.getIRVariable().toString() }

0 commit comments

Comments
 (0)