Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Use an IPA type rather than negative indexes for argument/parameter matching in data flow #7541

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -63,7 +63,7 @@ private module VirtualDispatch {
this.flowsFrom(other, allowOtherFromArg)
|
// Call argument
exists(DataFlowCall call, int i |
exists(DataFlowCall call, Position i |
other
.(DataFlow::ParameterNode)
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
@@ -268,16 +268,6 @@ Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
)
}

/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
}

/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
}

/** Holds if arguments at position `apos` match parameters at position `ppos`. */
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
@@ -27,7 +27,7 @@ abstract class ArgumentNode extends OperandNode {
* Holds if this argument occurs at the given position in the given call.
* The instance argument is considered to have index `-1`.
*/
abstract predicate argumentOf(DataFlowCall call, int pos);
abstract predicate argumentOf(DataFlowCall call, ArgumentPosition pos);

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

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

override predicate argumentOf(DataFlowCall call, int pos) { op = call.getArgumentOperand(pos) }
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
}

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

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

override predicate argumentOf(DataFlowCall call, int pos) {
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
read.getPrimaryInstruction() = call and
pos = getArgumentPosOfSideEffect(read.getIndex())
pos.(IndirectionPosition).getIndex() = read.getIndex()
}

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

/** A parameter position represented by an integer. */
class ParameterPosition = Position;

/** An argument position represented by an integer. */
class ArgumentPosition = Position;

class Position extends TPosition {
abstract string toString();
}

class DirectPosition extends TDirectPosition {
int index;

DirectPosition() { this = TDirectPosition(index) }

string toString() {
index = -1 and
result = "this"
or
index != -1 and
result = index.toString()
}

int getIndex() { result = index }
}

class IndirectionPosition extends TIndirectionPosition {
int index;

IndirectionPosition() { this = TIndirectionPosition(index) }

string toString() {
index = -1 and
result = "this"
or
index != -1 and
result = index.toString()
}

int getIndex() { result = index }
}

newtype TPosition =
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
TIndirectionPosition(int index) {
exists(ReadSideEffectInstruction instr | instr.getIndex() = index)
}

private newtype TReturnKind =
TNormalReturnKind() or
TIndirectReturnKind(ParameterIndex index)
@@ -490,19 +490,6 @@ class ExprNode extends InstructionNode {
override string toString() { result = this.asConvertedExpr().toString() }
}

/**
* INTERNAL: do not use. Translates a parameter/argument index into a negative
* number that denotes the index of its side effect (pointer indirection).
*/
bindingset[index]
int getArgumentPosOfSideEffect(int index) {
// -1 -> -2
// 0 -> -3
// 1 -> -4
// ...
result = -3 - index
}

/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -525,7 +512,7 @@ class ParameterNode extends InstructionNode {
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
predicate isParameterOf(Function f, int pos) { none() } // overridden by subclasses
predicate isParameterOf(Function f, ParameterPosition pos) { none() } // overridden by subclasses
}

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

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

override predicate isParameterOf(Function f, int pos) {
f.getParameter(pos) = instr.getParameter()
override predicate isParameterOf(Function f, ParameterPosition pos) {
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
}

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

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

override predicate isParameterOf(Function f, int pos) {
pos = -1 and instr.getEnclosingFunction() = f
override predicate isParameterOf(Function f, ParameterPosition pos) {
pos.(DirectPosition).getIndex() = -1 and instr.getEnclosingFunction() = f
}

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

override predicate isParameterOf(Function f, int pos) {
override predicate isParameterOf(Function f, ParameterPosition pos) {
exists(int index |
instr.getEnclosingFunction() = f and
instr.hasIndex(index)
|
pos = getArgumentPosOfSideEffect(index)
pos.(IndirectionPosition).getIndex() = index
)
}