C++: Define indirect instructions (and operands) using a 'Node0Impl' column instead of an instruction (or operand).

This commit is contained in:
Mathias Vorreiter Pedersen
2023-10-30 11:49:26 +00:00
parent c4521a30aa
commit 535d1e2565

View File

@@ -44,11 +44,12 @@ private newtype TIRDataFlowNode =
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) { TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
Ssa::isModifiableByCall(operand, indirectionIndex) Ssa::isModifiableByCall(operand, indirectionIndex)
} or } or
TRawIndirectOperand(Operand op, int indirectionIndex) { TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
Ssa::hasRawIndirectOperand(op, indirectionIndex) Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
} or } or
TRawIndirectInstruction(Instruction instr, int indirectionIndex) { TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
Ssa::hasRawIndirectInstruction(instr, indirectionIndex) not exists(node.asOperand()) and
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
} or } or
TFinalParameterNode(Parameter p, int indirectionIndex) { TFinalParameterNode(Parameter p, int indirectionIndex) {
exists(Ssa::FinalParameterUse use | exists(Ssa::FinalParameterUse use |
@@ -918,31 +919,34 @@ Type getTypeImpl(Type t, int indirectionIndex) {
result instanceof UnknownType result instanceof UnknownType
} }
/** private module RawIndirectNodes {
/**
* INTERNAL: Do not use. * INTERNAL: Do not use.
* *
* A node that represents the indirect value of an operand in the IR * A node that represents the indirect value of an operand in the IR
* after `index` number of loads. * after `index` number of loads.
*/ */
class RawIndirectOperand extends Node, TRawIndirectOperand { private class RawIndirectOperand0 extends Node, TRawIndirectOperand0 {
Operand operand; Node0Impl node;
int indirectionIndex; int indirectionIndex;
RawIndirectOperand() { this = TRawIndirectOperand(operand, indirectionIndex) } RawIndirectOperand0() { this = TRawIndirectOperand0(node, indirectionIndex) }
/** Gets the underlying instruction. */ /** Gets the underlying instruction. */
Operand getOperand() { result = operand } Operand getOperand() { result = node.asOperand() }
/** Gets the underlying indirection index. */ /** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex } int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getOperand().getDef().getEnclosingFunction() } override Declaration getFunction() {
result = this.getOperand().getDef().getEnclosingFunction()
}
override Declaration getEnclosingCallable() { result = this.getFunction() } override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() { override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue | exists(int sub, DataFlowType type, boolean isGLValue |
type = getOperandType(operand, isGLValue) and type = getOperandType(this.getOperand(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0 if isGLValue = true then sub = 1 else sub = 0
| |
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub) result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
@@ -958,8 +962,103 @@ class RawIndirectOperand extends Node, TRawIndirectOperand {
override string toStringImpl() { override string toStringImpl() {
result = operandNode(this.getOperand()).toStringImpl() + " indirection" result = operandNode(this.getOperand()).toStringImpl() + " indirection"
} }
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after `index` number of loads.
*/
private class RawIndirectInstruction0 extends Node, TRawIndirectInstruction0 {
Node0Impl node;
int indirectionIndex;
RawIndirectInstruction0() { this = TRawIndirectInstruction0(node, indirectionIndex) }
/** Gets the underlying instruction. */
Instruction getInstruction() { result = node.asInstruction() }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getInstructionType(this.getInstruction(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
}
final override Location getLocationImpl() {
if exists(this.getInstruction().getLocation())
then result = this.getInstruction().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
}
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an operand in the IR
* after a number of loads.
*/
class RawIndirectOperand extends Node {
int indirectionIndex;
Operand operand;
RawIndirectOperand() {
exists(Node0Impl node | operand = node.asOperand() |
this = TRawIndirectOperand0(node, indirectionIndex)
or
this = TRawIndirectInstruction0(node, indirectionIndex)
)
}
/** Gets the operand associated with this node. */
Operand getOperand() { result = operand }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after a number of loads.
*/
class RawIndirectInstruction extends Node {
int indirectionIndex;
Instruction instr;
RawIndirectInstruction() {
exists(Node0Impl node | instr = node.asInstruction() |
this = TRawIndirectOperand0(node, indirectionIndex)
or
this = TRawIndirectInstruction0(node, indirectionIndex)
)
}
/** Gets the instruction associated with this node. */
Instruction getInstruction() { result = instr }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
}
} }
import RawIndirectNodes
/** /**
* INTERNAL: do not use. * INTERNAL: do not use.
* *
@@ -1021,48 +1120,6 @@ class UninitializedNode extends Node {
LocalVariable getLocalVariable() { result = v } LocalVariable getLocalVariable() { result = v }
} }
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after `index` number of loads.
*/
class RawIndirectInstruction extends Node, TRawIndirectInstruction {
Instruction instr;
int indirectionIndex;
RawIndirectInstruction() { this = TRawIndirectInstruction(instr, indirectionIndex) }
/** Gets the underlying instruction. */
Instruction getInstruction() { result = instr }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getInstructionType(instr, isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
}
final override Location getLocationImpl() {
if exists(this.getInstruction().getLocation())
then result = this.getInstruction().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
}
}
private module GetConvertedResultExpression { private module GetConvertedResultExpression {
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
@@ -1600,6 +1657,8 @@ private module Cached {
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) } predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) { private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) {
nodeFrom != nodeTo and
(
// Reduce the indirection count by 1 if we're passing through a `LoadInstruction`. // Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
exists(int ind, LoadInstruction load | exists(int ind, LoadInstruction load |
hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and
@@ -1621,6 +1680,7 @@ private module Cached {
pragma[only_bind_into](indirectionIndex)) and pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex)) hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex))
) )
)
} }
/** /**
@@ -1645,6 +1705,7 @@ private module Cached {
private predicate indirectionInstructionFlow( private predicate indirectionInstructionFlow(
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
) { ) {
nodeFrom != nodeTo and
// If there's flow from an instruction to an operand, then there's also flow from the // If there's flow from an instruction to an operand, then there's also flow from the
// indirect instruction to the indirect operand. // indirect instruction to the indirect operand.
exists(Operand operand, Instruction instr, int indirectionIndex | exists(Operand operand, Instruction instr, int indirectionIndex |