diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index cd52f68c58b8..2f399a24e2d9 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -28,11 +28,7 @@ private class PrimaryArgumentNode extends ArgumentNode { PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) } - override predicate argumentOf(DataFlowCall call, int pos) { - op = call.getPositionalArgumentOperand(pos) - or - op = call.getThisArgumentOperand() and pos = -1 - } + override predicate argumentOf(DataFlowCall call, int pos) { op = call.getArgumentOperand(pos) } override string toString() { result = "Argument " + op.(PositionalArgumentOperand).getIndex() @@ -110,10 +106,10 @@ class ReturnIndirectionNode extends ReturnNode { override ReturnIndirectionInstruction primary; override ReturnKind getKind() { - result = TIndirectReturnKind(-1) and - primary.isThisIndirection() - or - result = TIndirectReturnKind(primary.getParameter().getIndex()) + exists(int index | + primary.hasIndex(index) and + result = TIndirectReturnKind(index) + ) } } @@ -500,13 +496,6 @@ class DataFlowType = IRType; /** A function call relevant for data flow. */ class DataFlowCall extends CallInstruction { - /** - * Gets the nth argument for this call. - * - * The range of `n` is from `0` to `getNumberOfArguments() - 1`. - */ - Node getArgument(int n) { result.asInstruction() = this.getPositionalArgument(n) } - Function getEnclosingCallable() { result = this.getEnclosingFunction() } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 445152552bd9..2fba66838e9c 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -266,10 +266,8 @@ class ParameterIndirectionNode extends ParameterNode { override predicate isParameterOf(Function f, int pos) { exists(int index | - f.getParameter(index) = instr.getParameter() - or - index = -1 and - instr.getIRVariable().(IRThisVariable).getEnclosingFunction() = f + instr.getEnclosingFunction() = f and + instr.hasIndex(index) | pos = getArgumentPosOfSideEffect(index) ) @@ -476,16 +474,8 @@ class DefinitionByReferenceNode extends InstructionNode { instr .getPrimaryInstruction() .(CallInstruction) - .getPositionalArgument(instr.getIndex()) + .getArgument(instr.getIndex()) .getUnconvertedResultExpression() - or - result = - instr - .getPrimaryInstruction() - .(CallInstruction) - .getThisArgument() - .getUnconvertedResultExpression() and - instr.getIndex() = -1 } /** Gets the parameter through which this value is assigned. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index dd5669413696..c6635264b647 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -588,6 +588,17 @@ class InitializeParameterInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the parameter with index `index`, or + * if `index` is `-1` and this instruction initializes `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +612,18 @@ class InitializeIndirectionInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the memory pointed to by the parameter with + * index `index`, or if `index` is `-1` and this instruction initializes the memory + * pointed to by `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +798,17 @@ class ReturnIndirectionInstruction extends VariableInstruction { * Holds if this instruction is the return indirection for `this`. */ final predicate isThisIndirection() { var instanceof IRThisVariable } + + /** + * Holds if this instruction is the return indirection for the parameter with index `index`, or + * if this instruction is the return indirection for `this` and `index` is `-1`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1621,22 @@ class CallInstruction extends Instruction { result = getPositionalArgumentOperand(index).getDef() } + /** + * Gets the argument operand at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final ArgumentOperand getArgumentOperand(int index) { + index >= 0 and result = getPositionalArgumentOperand(index) + or + index = -1 and result = getThisArgumentOperand() + } + + /** + * Gets the argument at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index dd5669413696..c6635264b647 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -588,6 +588,17 @@ class InitializeParameterInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the parameter with index `index`, or + * if `index` is `-1` and this instruction initializes `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +612,18 @@ class InitializeIndirectionInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the memory pointed to by the parameter with + * index `index`, or if `index` is `-1` and this instruction initializes the memory + * pointed to by `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +798,17 @@ class ReturnIndirectionInstruction extends VariableInstruction { * Holds if this instruction is the return indirection for `this`. */ final predicate isThisIndirection() { var instanceof IRThisVariable } + + /** + * Holds if this instruction is the return indirection for the parameter with index `index`, or + * if this instruction is the return indirection for `this` and `index` is `-1`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1621,22 @@ class CallInstruction extends Instruction { result = getPositionalArgumentOperand(index).getDef() } + /** + * Gets the argument operand at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final ArgumentOperand getArgumentOperand(int index) { + index >= 0 and result = getPositionalArgumentOperand(index) + or + index = -1 and result = getThisArgumentOperand() + } + + /** + * Gets the argument at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index dd5669413696..c6635264b647 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -588,6 +588,17 @@ class InitializeParameterInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the parameter with index `index`, or + * if `index` is `-1` and this instruction initializes `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +612,18 @@ class InitializeIndirectionInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the memory pointed to by the parameter with + * index `index`, or if `index` is `-1` and this instruction initializes the memory + * pointed to by `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +798,17 @@ class ReturnIndirectionInstruction extends VariableInstruction { * Holds if this instruction is the return indirection for `this`. */ final predicate isThisIndirection() { var instanceof IRThisVariable } + + /** + * Holds if this instruction is the return indirection for the parameter with index `index`, or + * if this instruction is the return indirection for `this` and `index` is `-1`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1621,22 @@ class CallInstruction extends Instruction { result = getPositionalArgumentOperand(index).getDef() } + /** + * Gets the argument operand at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final ArgumentOperand getArgumentOperand(int index) { + index >= 0 and result = getPositionalArgumentOperand(index) + or + index = -1 and result = getThisArgumentOperand() + } + + /** + * Gets the argument at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index dd5669413696..c6635264b647 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -588,6 +588,17 @@ class InitializeParameterInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the parameter with index `index`, or + * if `index` is `-1` and this instruction initializes `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +612,18 @@ class InitializeIndirectionInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the memory pointed to by the parameter with + * index `index`, or if `index` is `-1` and this instruction initializes the memory + * pointed to by `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +798,17 @@ class ReturnIndirectionInstruction extends VariableInstruction { * Holds if this instruction is the return indirection for `this`. */ final predicate isThisIndirection() { var instanceof IRThisVariable } + + /** + * Holds if this instruction is the return indirection for the parameter with index `index`, or + * if this instruction is the return indirection for `this` and `index` is `-1`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1621,22 @@ class CallInstruction extends Instruction { result = getPositionalArgumentOperand(index).getDef() } + /** + * Gets the argument operand at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final ArgumentOperand getArgumentOperand(int index) { + index >= 0 and result = getPositionalArgumentOperand(index) + or + index = -1 and result = getThisArgumentOperand() + } + + /** + * Gets the argument at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index dd5669413696..c6635264b647 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -588,6 +588,17 @@ class InitializeParameterInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the parameter with index `index`, or + * if `index` is `-1` and this instruction initializes `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +612,18 @@ class InitializeIndirectionInstruction extends VariableInstruction { * Gets the parameter initialized by this instruction. */ final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } + + /** + * Holds if this instruction initializes the memory pointed to by the parameter with + * index `index`, or if `index` is `-1` and this instruction initializes the memory + * pointed to by `this`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +798,17 @@ class ReturnIndirectionInstruction extends VariableInstruction { * Holds if this instruction is the return indirection for `this`. */ final predicate isThisIndirection() { var instanceof IRThisVariable } + + /** + * Holds if this instruction is the return indirection for the parameter with index `index`, or + * if this instruction is the return indirection for `this` and `index` is `-1`. + */ + pragma[noinline] + final predicate hasIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1621,22 @@ class CallInstruction extends Instruction { result = getPositionalArgumentOperand(index).getDef() } + /** + * Gets the argument operand at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final ArgumentOperand getArgumentOperand(int index) { + index >= 0 and result = getPositionalArgumentOperand(index) + or + index = -1 and result = getThisArgumentOperand() + } + + /** + * Gets the argument at the specified index, or `this` if `index` is `-1`. + */ + pragma[noinline] + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */