From 416431a7c1e044ac724ec05dfae0cfabb81f3eab Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 20 Nov 2020 12:22:37 +0100 Subject: [PATCH 1/7] C++: Add convenience predicates for working with qualifiers as parameters. --- .../aliased_ssa/Instruction.qll | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) 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..694810e0e8f2 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,16 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +611,17 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +796,16 @@ 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`. + */ + final predicate isParameterOrThisIndirection(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1618,24 @@ 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 getPositionalOrThisArgumentOperand(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 getPositionalOrThisArgument(int index) { + result = getPositionalOrThisArgumentOperand(index).getDef() + } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ From f3b5d7b8303052cc7646337af18247af810bdb3e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 20 Nov 2020 12:23:34 +0100 Subject: [PATCH 2/7] C++/C#: Sync identical files --- .../cpp/ir/implementation/raw/Instruction.qll | 49 +++++++++++++++++++ .../unaliased_ssa/Instruction.qll | 49 +++++++++++++++++++ .../ir/implementation/raw/Instruction.qll | 49 +++++++++++++++++++ .../unaliased_ssa/Instruction.qll | 49 +++++++++++++++++++ 4 files changed, 196 insertions(+) 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..694810e0e8f2 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,16 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +611,17 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +796,16 @@ 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`. + */ + final predicate isParameterOrThisIndirection(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1618,24 @@ 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 getPositionalOrThisArgumentOperand(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 getPositionalOrThisArgument(int index) { + result = getPositionalOrThisArgumentOperand(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..694810e0e8f2 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,16 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +611,17 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +796,16 @@ 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`. + */ + final predicate isParameterOrThisIndirection(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1618,24 @@ 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 getPositionalOrThisArgumentOperand(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 getPositionalOrThisArgument(int index) { + result = getPositionalOrThisArgumentOperand(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..694810e0e8f2 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -588,6 +588,16 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +611,17 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +796,16 @@ 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`. + */ + final predicate isParameterOrThisIndirection(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1618,24 @@ 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 getPositionalOrThisArgumentOperand(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 getPositionalOrThisArgument(int index) { + result = getPositionalOrThisArgumentOperand(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..694810e0e8f2 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,16 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -601,6 +611,17 @@ 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`. + */ + final predicate isParameterOrQualifierIndex(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.getIRVariable() instanceof IRThisVariable + } } /** @@ -775,6 +796,16 @@ 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`. + */ + final predicate isParameterOrThisIndirection(int index) { + index >= 0 and index = this.getParameter().getIndex() + or + index = -1 and this.isThisIndirection() + } } /** @@ -1587,6 +1618,24 @@ 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 getPositionalOrThisArgumentOperand(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 getPositionalOrThisArgument(int index) { + result = getPositionalOrThisArgumentOperand(index).getDef() + } + /** * Gets the number of arguments of the call, including the `this` pointer, if any. */ From c7efc91676ca138cc9b00fc88dd17ba8f96c3117 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 20 Nov 2020 12:24:39 +0100 Subject: [PATCH 3/7] C++: Use the new predicates in IR dataflow. --- .../cpp/ir/dataflow/internal/DataFlowPrivate.qll | 12 +++++------- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 16 +++------------- 2 files changed, 8 insertions(+), 20 deletions(-) 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..1ac9d5586ba0 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 @@ -29,9 +29,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 + op = call.getPositionalOrThisArgumentOperand(pos) } override string toString() { @@ -110,10 +108,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.isParameterOrThisIndirection(index) and + result = TIndirectReturnKind(index) + ) } } 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..6eb1212a8c14 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.isParameterOrQualifierIndex(index) | pos = getArgumentPosOfSideEffect(index) ) @@ -476,16 +474,8 @@ class DefinitionByReferenceNode extends InstructionNode { instr .getPrimaryInstruction() .(CallInstruction) - .getPositionalArgument(instr.getIndex()) + .getPositionalOrThisArgument(instr.getIndex()) .getUnconvertedResultExpression() - or - result = - instr - .getPrimaryInstruction() - .(CallInstruction) - .getThisArgument() - .getUnconvertedResultExpression() and - instr.getIndex() = -1 } /** Gets the parameter through which this value is assigned. */ From f173dc71c0f140235ab2e0c8767e24dab2a53c9c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sat, 21 Nov 2020 00:54:50 +0100 Subject: [PATCH 4/7] C++: Use shorter names for new IR predicates. This should hopefully guide users to use these predicates by default. --- .../ir/implementation/aliased_ssa/Instruction.qll | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 694810e0e8f2..07f36584100b 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 @@ -593,7 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * Holds if this instruction initializes the parameter with index `index`, or * if `index` is `-1` and this instruction initializes `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -617,7 +617,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * index `index`, or if `index` is `-1` and this instruction initializes the memory * pointed to by `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -801,7 +801,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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`. */ - final predicate isParameterOrThisIndirection(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.isThisIndirection() @@ -1622,7 +1622,7 @@ class CallInstruction extends Instruction { * Gets the argument operand at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final ArgumentOperand getPositionalOrThisArgumentOperand(int index) { + final ArgumentOperand getArgumentOperand(int index) { index >= 0 and result = getPositionalArgumentOperand(index) or index = -1 and result = getThisArgumentOperand() @@ -1632,9 +1632,7 @@ class CallInstruction extends Instruction { * Gets the argument at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final Instruction getPositionalOrThisArgument(int index) { - result = getPositionalOrThisArgumentOperand(index).getDef() - } + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } /** * Gets the number of arguments of the call, including the `this` pointer, if any. From 61bbceb201dc15539f6af926bd8879517373caca Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sat, 21 Nov 2020 00:55:07 +0100 Subject: [PATCH 5/7] C++/C#: Sync identical files --- .../code/cpp/ir/implementation/raw/Instruction.qll | 12 +++++------- .../ir/implementation/unaliased_ssa/Instruction.qll | 12 +++++------- .../ir/implementation/raw/Instruction.qll | 12 +++++------- .../ir/implementation/unaliased_ssa/Instruction.qll | 12 +++++------- 4 files changed, 20 insertions(+), 28 deletions(-) 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 694810e0e8f2..07f36584100b 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 @@ -593,7 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * Holds if this instruction initializes the parameter with index `index`, or * if `index` is `-1` and this instruction initializes `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -617,7 +617,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * index `index`, or if `index` is `-1` and this instruction initializes the memory * pointed to by `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -801,7 +801,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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`. */ - final predicate isParameterOrThisIndirection(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.isThisIndirection() @@ -1622,7 +1622,7 @@ class CallInstruction extends Instruction { * Gets the argument operand at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final ArgumentOperand getPositionalOrThisArgumentOperand(int index) { + final ArgumentOperand getArgumentOperand(int index) { index >= 0 and result = getPositionalArgumentOperand(index) or index = -1 and result = getThisArgumentOperand() @@ -1632,9 +1632,7 @@ class CallInstruction extends Instruction { * Gets the argument at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final Instruction getPositionalOrThisArgument(int index) { - result = getPositionalOrThisArgumentOperand(index).getDef() - } + 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 694810e0e8f2..07f36584100b 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 @@ -593,7 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * Holds if this instruction initializes the parameter with index `index`, or * if `index` is `-1` and this instruction initializes `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -617,7 +617,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * index `index`, or if `index` is `-1` and this instruction initializes the memory * pointed to by `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -801,7 +801,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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`. */ - final predicate isParameterOrThisIndirection(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.isThisIndirection() @@ -1622,7 +1622,7 @@ class CallInstruction extends Instruction { * Gets the argument operand at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final ArgumentOperand getPositionalOrThisArgumentOperand(int index) { + final ArgumentOperand getArgumentOperand(int index) { index >= 0 and result = getPositionalArgumentOperand(index) or index = -1 and result = getThisArgumentOperand() @@ -1632,9 +1632,7 @@ class CallInstruction extends Instruction { * Gets the argument at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final Instruction getPositionalOrThisArgument(int index) { - result = getPositionalOrThisArgumentOperand(index).getDef() - } + 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 694810e0e8f2..07f36584100b 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -593,7 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * Holds if this instruction initializes the parameter with index `index`, or * if `index` is `-1` and this instruction initializes `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -617,7 +617,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * index `index`, or if `index` is `-1` and this instruction initializes the memory * pointed to by `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -801,7 +801,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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`. */ - final predicate isParameterOrThisIndirection(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.isThisIndirection() @@ -1622,7 +1622,7 @@ class CallInstruction extends Instruction { * Gets the argument operand at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final ArgumentOperand getPositionalOrThisArgumentOperand(int index) { + final ArgumentOperand getArgumentOperand(int index) { index >= 0 and result = getPositionalArgumentOperand(index) or index = -1 and result = getThisArgumentOperand() @@ -1632,9 +1632,7 @@ class CallInstruction extends Instruction { * Gets the argument at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final Instruction getPositionalOrThisArgument(int index) { - result = getPositionalOrThisArgumentOperand(index).getDef() - } + 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 694810e0e8f2..07f36584100b 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -593,7 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * Holds if this instruction initializes the parameter with index `index`, or * if `index` is `-1` and this instruction initializes `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -617,7 +617,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * index `index`, or if `index` is `-1` and this instruction initializes the memory * pointed to by `this`. */ - final predicate isParameterOrQualifierIndex(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.getIRVariable() instanceof IRThisVariable @@ -801,7 +801,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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`. */ - final predicate isParameterOrThisIndirection(int index) { + final predicate hasIndex(int index) { index >= 0 and index = this.getParameter().getIndex() or index = -1 and this.isThisIndirection() @@ -1622,7 +1622,7 @@ class CallInstruction extends Instruction { * Gets the argument operand at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final ArgumentOperand getPositionalOrThisArgumentOperand(int index) { + final ArgumentOperand getArgumentOperand(int index) { index >= 0 and result = getPositionalArgumentOperand(index) or index = -1 and result = getThisArgumentOperand() @@ -1632,9 +1632,7 @@ class CallInstruction extends Instruction { * Gets the argument at the specified index, or `this` if `index` is `-1`. */ pragma[noinline] - final Instruction getPositionalOrThisArgument(int index) { - result = getPositionalOrThisArgumentOperand(index).getDef() - } + final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() } /** * Gets the number of arguments of the call, including the `this` pointer, if any. From a7644db762603f1f5a3c481a8c573e68e89e2483 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sat, 21 Nov 2020 01:00:59 +0100 Subject: [PATCH 6/7] C++: Use the new names in IR dataflow. Turns out DataFlowCall had its own implementation of getArgument already (which didn't handle qualifiers). The predicate wasn't used anywhere, so I simply removed it, as a better predicate is now available on the base class of DataFlowCall. --- .../cpp/ir/dataflow/internal/DataFlowPrivate.qll | 13 ++----------- .../code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) 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 1ac9d5586ba0..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,9 +28,7 @@ private class PrimaryArgumentNode extends ArgumentNode { PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) } - override predicate argumentOf(DataFlowCall call, int pos) { - op = call.getPositionalOrThisArgumentOperand(pos) - } + override predicate argumentOf(DataFlowCall call, int pos) { op = call.getArgumentOperand(pos) } override string toString() { result = "Argument " + op.(PositionalArgumentOperand).getIndex() @@ -109,7 +107,7 @@ class ReturnIndirectionNode extends ReturnNode { override ReturnKind getKind() { exists(int index | - primary.isParameterOrThisIndirection(index) and + primary.hasIndex(index) and result = TIndirectReturnKind(index) ) } @@ -498,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 6eb1212a8c14..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 @@ -267,7 +267,7 @@ class ParameterIndirectionNode extends ParameterNode { override predicate isParameterOf(Function f, int pos) { exists(int index | instr.getEnclosingFunction() = f and - instr.isParameterOrQualifierIndex(index) + instr.hasIndex(index) | pos = getArgumentPosOfSideEffect(index) ) @@ -474,7 +474,7 @@ class DefinitionByReferenceNode extends InstructionNode { instr .getPrimaryInstruction() .(CallInstruction) - .getPositionalOrThisArgument(instr.getIndex()) + .getArgument(instr.getIndex()) .getUnconvertedResultExpression() } From 08f8660b17d6d071f6bd54071ba011286b706f94 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 24 Nov 2020 10:45:02 +0100 Subject: [PATCH 7/7] C++/C#: Add pragma[noinline] to hasIndex predicates. --- .../code/cpp/ir/implementation/aliased_ssa/Instruction.qll | 3 +++ .../src/semmle/code/cpp/ir/implementation/raw/Instruction.qll | 3 +++ .../code/cpp/ir/implementation/unaliased_ssa/Instruction.qll | 3 +++ .../ql/src/experimental/ir/implementation/raw/Instruction.qll | 3 +++ .../ir/implementation/unaliased_ssa/Instruction.qll | 3 +++ 5 files changed, 15 insertions(+) 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 07f36584100b..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 @@ -593,6 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * 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 @@ -617,6 +618,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * 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 @@ -801,6 +803,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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 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 07f36584100b..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 @@ -593,6 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * 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 @@ -617,6 +618,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * 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 @@ -801,6 +803,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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 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 07f36584100b..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 @@ -593,6 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * 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 @@ -617,6 +618,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * 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 @@ -801,6 +803,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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 diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index 07f36584100b..c6635264b647 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -593,6 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * 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 @@ -617,6 +618,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * 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 @@ -801,6 +803,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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 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 07f36584100b..c6635264b647 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -593,6 +593,7 @@ class InitializeParameterInstruction extends VariableInstruction { * 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 @@ -617,6 +618,7 @@ class InitializeIndirectionInstruction extends VariableInstruction { * 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 @@ -801,6 +803,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * 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