mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Merge pull request #1101 from robertbrignull/merge/rc/1.20
Merge rc/1.20 => master
This commit is contained in:
@@ -80,6 +80,7 @@ private predicate allocReaches0(Expr e, Expr alloc, string kind) {
|
||||
) or exists(Variable v |
|
||||
// alloc via a global
|
||||
allocReachesVariable(v, alloc, kind) and
|
||||
strictcount(VariableAccess va | va.getTarget() = v) <= 50 and // avoid very expensive cases
|
||||
e.(VariableAccess).getTarget() = v
|
||||
)
|
||||
}
|
||||
|
||||
@@ -237,15 +237,8 @@ module FlowVar_internal {
|
||||
|
||||
override VariableAccess getAnAccess() {
|
||||
exists(SubBasicBlock reached |
|
||||
reached = getAReachedBlockVarSBB(this)
|
||||
|
|
||||
reached = getAReachedBlockVarSBB(this) and
|
||||
variableAccessInSBB(v, reached, result)
|
||||
or
|
||||
// Allow flow into a `VariableAccess` that is used as definition by
|
||||
// reference. This flow is blocked by `getAReachedBlockVarSBB` because
|
||||
// flow should not propagate past that.
|
||||
result = reached.getASuccessor().(VariableAccess) and
|
||||
blockVarDefinedByReference(result, v, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -420,6 +413,12 @@ module FlowVar_internal {
|
||||
va.getTarget() = v and
|
||||
va = sbb.getANode() and
|
||||
not overwrite(va, _)
|
||||
or
|
||||
// Allow flow into a `VariableAccess` that is used as definition by
|
||||
// reference. This flow is blocked by `getAReachedBlockVarSBB` because
|
||||
// flow should not propagate past that.
|
||||
va = sbb.getASuccessor().(VariableAccess) and
|
||||
blockVarDefinedByReference(va, v, _)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import Instruction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
|
||||
@@ -63,8 +63,8 @@ class IRBlockBase extends TIRBlock {
|
||||
result = getInstructionCount(this)
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getFirstInstruction(this).getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
final Function getEnclosingFunction() {
|
||||
@@ -116,7 +116,7 @@ class IRBlock extends IRBlockBase {
|
||||
* Holds if this block is reachable from the entry point of its function
|
||||
*/
|
||||
final predicate isReachableFromFunctionEntry() {
|
||||
this = getEnclosingFunctionIR().getEntryBlock() or
|
||||
this = getEnclosingIRFunction().getEntryBlock() or
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@ private import internal.IRInternal
|
||||
import Instruction
|
||||
import cpp
|
||||
|
||||
private newtype TFunctionIR =
|
||||
MkFunctionIR(Function func) {
|
||||
private newtype TIRFunction =
|
||||
MkIRFunction(Function func) {
|
||||
Construction::functionHasIR(func)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the IR for a function.
|
||||
*/
|
||||
class FunctionIR extends TFunctionIR {
|
||||
class IRFunction extends TIRFunction {
|
||||
Function func;
|
||||
|
||||
FunctionIR() {
|
||||
this = MkFunctionIR(func)
|
||||
IRFunction() {
|
||||
this = MkIRFunction(func)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ReturnInstruction getReturnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final IRReturnVariable getReturnVariable() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
|
||||
* Gets all instructions in this function.
|
||||
*/
|
||||
final Instruction getAnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all blocks in this function.
|
||||
*/
|
||||
final IRBlock getABlock() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.TempVariableTag
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
@@ -48,7 +48,7 @@ abstract class IRVariable extends TIRVariable {
|
||||
/**
|
||||
* Gets the IR for the function that references this variable.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result.getFunction() = func
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
import Operand
|
||||
@@ -15,7 +15,7 @@ module InstructionSanity {
|
||||
/**
|
||||
* Holds if the instruction `instr` should be expected to have an operand
|
||||
* with operand tag `tag`. Only holds for singleton operand tags. Tags with
|
||||
* parameters, such as `PhiOperand` and `PositionalArgumentOperand` are handled
|
||||
* parameters, such as `PhiInputOperand` and `PositionalArgumentOperand` are handled
|
||||
* separately in `unexpectedOperand`.
|
||||
*/
|
||||
private predicate expectsOperand(Instruction instr, OperandTag tag) {
|
||||
@@ -87,7 +87,7 @@ module InstructionSanity {
|
||||
*/
|
||||
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
|
||||
pred = instr.getBlock().getAPredecessor() and
|
||||
not exists(PhiOperand operand |
|
||||
not exists(PhiInputOperand operand |
|
||||
operand = instr.getAnOperand() and
|
||||
operand.getPredecessorBlock() = pred
|
||||
)
|
||||
@@ -153,7 +153,7 @@ module InstructionSanity {
|
||||
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
|
||||
operand.getUseInstruction() = instr and
|
||||
operand.getDefinitionInstruction() = defInstr and
|
||||
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
|
||||
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,10 +174,10 @@ module InstructionSanity {
|
||||
*
|
||||
* This check ensures we don't have too _few_ back edges.
|
||||
*/
|
||||
query predicate containsLoopOfForwardEdges(FunctionIR f) {
|
||||
query predicate containsLoopOfForwardEdges(IRFunction f) {
|
||||
exists(IRBlock block |
|
||||
forwardEdge+(block, block) and
|
||||
block.getEnclosingFunctionIR() = f
|
||||
block.getEnclosingIRFunction() = f
|
||||
)
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ module InstructionSanity {
|
||||
* This check ensures we don't have too _many_ back edges.
|
||||
*/
|
||||
query predicate lostReachability(IRBlock block) {
|
||||
exists(FunctionIR f, IRBlock entry |
|
||||
exists(IRFunction f, IRBlock entry |
|
||||
entry = f.getEntryBlock() and
|
||||
entry.getASuccessor+() = block and
|
||||
not forwardEdge+(entry, block) and
|
||||
@@ -373,14 +373,14 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getEnclosingFunction() {
|
||||
result = getEnclosingFunctionIR().getFunction()
|
||||
result = getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
* Gets the IRFunction object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = Construction::getInstructionEnclosingIRFunction(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1622,15 +1622,22 @@ class PhiInstruction extends Instruction {
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
|
||||
*/
|
||||
final PhiInputOperand getAnInputOperand() {
|
||||
result = this.getAnOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that defines the input to one of the operands of this
|
||||
* instruction. It's possible for more than one operand to have the same
|
||||
* defining instruction, so this predicate will have the same number of
|
||||
* results as `getAnOperand()` or fewer.
|
||||
* results as `getAnInputOperand()` or fewer.
|
||||
*/
|
||||
pragma[noinline]
|
||||
final Instruction getAnOperandDefinitionInstruction() {
|
||||
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
|
||||
final Instruction getAnInput() {
|
||||
result = this.getAnInputOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ class Operand extends TOperand {
|
||||
result = getUseInstruction().getLocation()
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getUseInstruction().getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getUseInstruction().getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,12 +379,12 @@ class SideEffectOperand extends TypedOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
|
||||
PhiOperand() {
|
||||
PhiInputOperand() {
|
||||
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableFunctionIR(FunctionIR funcIR) {
|
||||
shouldPrintFunction(funcIR.getFunction())
|
||||
TPrintableIRFunction(IRFunction irFunc) {
|
||||
shouldPrintFunction(irFunc.getFunction())
|
||||
} or
|
||||
TPrintableIRBlock(IRBlock block) {
|
||||
shouldPrintFunction(block.getEnclosingFunction())
|
||||
@@ -113,30 +113,30 @@ abstract class PrintableIRNode extends TPrintableIRNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* An IR graph node representing a `FunctionIR` object.
|
||||
* An IR graph node representing a `IRFunction` object.
|
||||
*/
|
||||
class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
FunctionIR funcIR;
|
||||
class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
|
||||
IRFunction irFunc;
|
||||
|
||||
PrintableFunctionIR() {
|
||||
this = TPrintableFunctionIR(funcIR)
|
||||
PrintableIRFunction() {
|
||||
this = TPrintableIRFunction(irFunc)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = funcIR.toString()
|
||||
result = irFunc.toString()
|
||||
}
|
||||
|
||||
override Location getLocation() {
|
||||
result = funcIR.getLocation()
|
||||
result = irFunc.getLocation()
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
result = getIdentityString(irFunc.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
this = rank[result + 1](PrintableFunctionIR orderedFunc, Location location |
|
||||
location = orderedFunc.getFunctionIR().getLocation() |
|
||||
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
|
||||
location = orderedFunc.getIRFunction().getLocation() |
|
||||
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), orderedFunc.getLabel()
|
||||
)
|
||||
@@ -146,8 +146,8 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
none()
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
final IRFunction getIRFunction() {
|
||||
result = irFunc
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,8 +185,8 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
|
||||
any()
|
||||
}
|
||||
|
||||
override final PrintableFunctionIR getParent() {
|
||||
result.getFunctionIR() = block.getEnclosingFunctionIR()
|
||||
override final PrintableIRFunction getParent() {
|
||||
result.getIRFunction() = block.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
override string getProperty(string key) {
|
||||
|
||||
@@ -10,8 +10,8 @@ int getConstantValue(Instruction instr) {
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
|
||||
result = max(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pragma[noinline]
|
||||
int getConstantValueToPhi(Instruction def) {
|
||||
exists(PhiInstruction phi |
|
||||
result = getConstantValue(def) and
|
||||
def = phi.getAnOperandDefinitionInstruction()
|
||||
def = phi.getAnInput()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,38 +19,38 @@ class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||
}
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
variableAddressValueNumber(_, funcIR, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeParameterValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
initializeParameterValueNumber(_, funcIR, var)
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(FunctionIR funcIR) {
|
||||
initializeThisValueNumber(_, funcIR)
|
||||
TInitializeThisValueNumber(IRFunction irFunc) {
|
||||
initializeThisValueNumber(_, irFunc)
|
||||
} or
|
||||
TConstantValueNumber(FunctionIR funcIR, Type type, string value) {
|
||||
constantValueNumber(_, funcIR, type, value)
|
||||
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
|
||||
constantValueNumber(_, irFunc, type, value)
|
||||
} or
|
||||
TFieldAddressValueNumber(FunctionIR funcIR, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, funcIR, field, objectAddress)
|
||||
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
TBinaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
binaryValueNumber(_, funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(FunctionIR funcIR, Opcode opcode, Type type, int elementSize,
|
||||
TPointerArithmeticValueNumber(IRFunction irFunc, Opcode opcode, Type type, int elementSize,
|
||||
ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
pointerArithmeticValueNumber(_, funcIR, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, funcIR, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
|
||||
TInheritanceConversionValueNumber(IRFunction irFunc, Opcode opcode, Class baseClass,
|
||||
Class derivedClass, ValueNumber operand) {
|
||||
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
|
||||
inheritanceConversionValueNumber(_, irFunc, opcode, baseClass, derivedClass, operand)
|
||||
} or
|
||||
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
|
||||
uniqueValueNumber(instr, funcIR)
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) {
|
||||
uniqueValueNumber(instr, irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,39 +134,39 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, IRFunction irFunc,
|
||||
IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
|
||||
FunctionIR funcIR, IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, IRVariable var) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
|
||||
private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFunc, Type type,
|
||||
string value) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
|
||||
Field field, ValueNumber objectAddress) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
valueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof PointerArithmeticInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -175,9 +175,9 @@ private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR,
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
@@ -185,9 +185,9 @@ private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction inst
|
||||
valueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -195,8 +195,8 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
|
||||
}
|
||||
|
||||
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getBaseClass() = baseClass and
|
||||
instr.getDerivedClass() = derivedClass and
|
||||
@@ -207,8 +207,8 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
|
||||
* Holds if `instr` should be assigned a unique value number because this library does not know how
|
||||
* to determine if two instances of that instruction are equivalent.
|
||||
*/
|
||||
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr.getResultType() instanceof VoidType) and
|
||||
not numberableInstruction(instr)
|
||||
}
|
||||
@@ -218,9 +218,9 @@ private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
*/
|
||||
cached ValueNumber valueNumber(Instruction instr) {
|
||||
result = nonUniqueValueNumber(instr) or
|
||||
exists(FunctionIR funcIR |
|
||||
uniqueValueNumber(instr, funcIR) and
|
||||
result = TUniqueValueNumber(funcIR, instr)
|
||||
exists(IRFunction irFunc |
|
||||
uniqueValueNumber(instr, irFunc) and
|
||||
result = TUniqueValueNumber(irFunc, instr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -236,47 +236,47 @@ ValueNumber valueNumberOfOperand(Operand op) {
|
||||
* value number.
|
||||
*/
|
||||
private ValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(FunctionIR funcIR |
|
||||
funcIR = instr.getEnclosingFunctionIR() and
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, funcIR, var) and
|
||||
result = TVariableAddressValueNumber(funcIR, var)
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
) or
|
||||
exists(IRVariable var |
|
||||
initializeParameterValueNumber(instr, funcIR, var) and
|
||||
result = TInitializeParameterValueNumber(funcIR, var)
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
) or
|
||||
(
|
||||
initializeThisValueNumber(instr, funcIR) and
|
||||
result = TInitializeThisValueNumber(funcIR)
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
) or
|
||||
exists(Type type, string value |
|
||||
constantValueNumber(instr, funcIR, type, value) and
|
||||
result = TConstantValueNumber(funcIR, type, value)
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
) or
|
||||
exists(Field field, ValueNumber objectAddress |
|
||||
fieldAddressValueNumber(instr, funcIR, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(funcIR, field, objectAddress)
|
||||
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber leftOperand, ValueNumber rightOperand |
|
||||
binaryValueNumber(instr, funcIR, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber operand |
|
||||
unaryValueNumber(instr, funcIR, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(funcIR, opcode, type, operand)
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
|
||||
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
|
||||
inheritanceConversionValueNumber(instr, irFunc, opcode, baseClass, derivedClass,
|
||||
operand) and
|
||||
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
result = TPointerArithmeticValueNumber(funcIR, opcode, type, elementSize, leftOperand,
|
||||
result = TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand)
|
||||
) or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
|
||||
@@ -73,7 +73,7 @@ private predicate operandEscapesDomain(Operand operand) {
|
||||
not isArgumentForParameter(_, operand, _) and
|
||||
not isOnlyEscapesViaReturnArgument(operand) and
|
||||
not operand.getUseInstruction() instanceof ReturnValueInstruction and
|
||||
not operand instanceof PhiOperand
|
||||
not operand instanceof PhiInputOperand
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,7 @@ private predicate operandEscapesNonReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUseInstruction())
|
||||
or
|
||||
operand instanceof PhiOperand and
|
||||
operand instanceof PhiInputOperand and
|
||||
resultEscapesNonReturn(operand.getUseInstruction())
|
||||
or
|
||||
operandEscapesDomain(operand)
|
||||
@@ -194,7 +194,7 @@ private predicate operandMayReachReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUseInstruction())
|
||||
or
|
||||
operand instanceof PhiOperand and
|
||||
operand instanceof PhiInputOperand and
|
||||
resultMayReachReturn(operand.getUseInstruction())
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ private newtype TVirtualVariable =
|
||||
TVirtualIRVariable(IRVariable var) {
|
||||
not variableAddressEscapes(var)
|
||||
} or
|
||||
TUnknownVirtualVariable(FunctionIR f)
|
||||
TUnknownVirtualVariable(IRFunction f)
|
||||
|
||||
private VirtualIRVariable getVirtualVariable(IRVariable var) {
|
||||
result.getIRVariable() = var
|
||||
}
|
||||
|
||||
private UnknownVirtualVariable getUnknownVirtualVariable(FunctionIR f) {
|
||||
result.getEnclosingFunctionIR() = f
|
||||
private UnknownVirtualVariable getUnknownVirtualVariable(IRFunction f) {
|
||||
result.getEnclosingIRFunction() = f
|
||||
}
|
||||
|
||||
class VirtualVariable extends TVirtualVariable {
|
||||
@@ -68,7 +68,7 @@ class VirtualIRVariable extends VirtualVariable, TVirtualIRVariable {
|
||||
* including escaped local variables.
|
||||
*/
|
||||
class UnknownVirtualVariable extends VirtualVariable, TUnknownVirtualVariable {
|
||||
FunctionIR f;
|
||||
IRFunction f;
|
||||
|
||||
UnknownVirtualVariable() {
|
||||
this = TUnknownVirtualVariable(f)
|
||||
@@ -86,7 +86,7 @@ class UnknownVirtualVariable extends VirtualVariable, TUnknownVirtualVariable {
|
||||
result instanceof UnknownType
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = f
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class VariableMemoryAccess extends TVariableMemoryAccess, MemoryAccess {
|
||||
|
||||
final override VirtualVariable getVirtualVariable() {
|
||||
result = getVirtualVariable(var) or
|
||||
not exists(getVirtualVariable(var)) and result = getUnknownVirtualVariable(var.getEnclosingFunctionIR())
|
||||
not exists(getVirtualVariable(var)) and result = getUnknownVirtualVariable(var.getEnclosingIRFunction())
|
||||
}
|
||||
|
||||
IntValue getStartBitOffset() {
|
||||
@@ -270,16 +270,16 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
|
||||
)
|
||||
)
|
||||
else (
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingFunctionIR()))
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingIRFunction()))
|
||||
)
|
||||
) or
|
||||
(
|
||||
kind instanceof EscapedMemoryAccess and
|
||||
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingFunctionIR()))
|
||||
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingIRFunction()))
|
||||
) or
|
||||
(
|
||||
kind instanceof EscapedMayMemoryAccess and
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingFunctionIR()))
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingIRFunction()))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -298,16 +298,16 @@ MemoryAccess getOperandMemoryAccess(MemoryOperand operand) {
|
||||
)
|
||||
)
|
||||
else (
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingFunctionIR()))
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingIRFunction()))
|
||||
)
|
||||
) or
|
||||
(
|
||||
kind instanceof EscapedMemoryAccess and
|
||||
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingFunctionIR()))
|
||||
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingIRFunction()))
|
||||
) or
|
||||
(
|
||||
kind instanceof EscapedMayMemoryAccess and
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingFunctionIR()))
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getEnclosingIRFunction()))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -15,8 +15,8 @@ cached private module Cached {
|
||||
}
|
||||
|
||||
cached predicate functionHasIR(Function func) {
|
||||
exists(OldIR::FunctionIR funcIR |
|
||||
funcIR.getFunction() = func
|
||||
exists(OldIR::IRFunction irFunc |
|
||||
irFunc.getFunction() = func
|
||||
)
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ cached private module Cached {
|
||||
)
|
||||
)
|
||||
else (
|
||||
result = instruction.getEnclosingFunctionIR().getUnmodeledDefinitionInstruction()
|
||||
result = instruction.getEnclosingIRFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
) or
|
||||
// Connect any definitions that are not being modeled in SSA to the
|
||||
@@ -118,7 +118,7 @@ cached private module Cached {
|
||||
instruction = Chi(getOldInstruction(result)) and
|
||||
tag instanceof ChiPartialOperandTag
|
||||
or
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
tag instanceof UnmodeledUseOperandTag and
|
||||
result = f.getUnmodeledDefinitionInstruction() and
|
||||
instruction = f.getUnmodeledUseInstruction()
|
||||
@@ -301,7 +301,7 @@ cached private module Cached {
|
||||
result instanceof Opcode::Unreached
|
||||
}
|
||||
|
||||
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
|
||||
cached IRFunction getInstructionEnclosingIRFunction(Instruction instruction) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = WrappedInstruction(oldInstruction)
|
||||
or
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import Instruction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
|
||||
@@ -63,8 +63,8 @@ class IRBlockBase extends TIRBlock {
|
||||
result = getInstructionCount(this)
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getFirstInstruction(this).getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
final Function getEnclosingFunction() {
|
||||
@@ -116,7 +116,7 @@ class IRBlock extends IRBlockBase {
|
||||
* Holds if this block is reachable from the entry point of its function
|
||||
*/
|
||||
final predicate isReachableFromFunctionEntry() {
|
||||
this = getEnclosingFunctionIR().getEntryBlock() or
|
||||
this = getEnclosingIRFunction().getEntryBlock() or
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@ private import internal.IRInternal
|
||||
import Instruction
|
||||
import cpp
|
||||
|
||||
private newtype TFunctionIR =
|
||||
MkFunctionIR(Function func) {
|
||||
private newtype TIRFunction =
|
||||
MkIRFunction(Function func) {
|
||||
Construction::functionHasIR(func)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the IR for a function.
|
||||
*/
|
||||
class FunctionIR extends TFunctionIR {
|
||||
class IRFunction extends TIRFunction {
|
||||
Function func;
|
||||
|
||||
FunctionIR() {
|
||||
this = MkFunctionIR(func)
|
||||
IRFunction() {
|
||||
this = MkIRFunction(func)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ReturnInstruction getReturnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final IRReturnVariable getReturnVariable() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
|
||||
* Gets all instructions in this function.
|
||||
*/
|
||||
final Instruction getAnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all blocks in this function.
|
||||
*/
|
||||
final IRBlock getABlock() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.TempVariableTag
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
@@ -48,7 +48,7 @@ abstract class IRVariable extends TIRVariable {
|
||||
/**
|
||||
* Gets the IR for the function that references this variable.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result.getFunction() = func
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
import Operand
|
||||
@@ -15,7 +15,7 @@ module InstructionSanity {
|
||||
/**
|
||||
* Holds if the instruction `instr` should be expected to have an operand
|
||||
* with operand tag `tag`. Only holds for singleton operand tags. Tags with
|
||||
* parameters, such as `PhiOperand` and `PositionalArgumentOperand` are handled
|
||||
* parameters, such as `PhiInputOperand` and `PositionalArgumentOperand` are handled
|
||||
* separately in `unexpectedOperand`.
|
||||
*/
|
||||
private predicate expectsOperand(Instruction instr, OperandTag tag) {
|
||||
@@ -87,7 +87,7 @@ module InstructionSanity {
|
||||
*/
|
||||
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
|
||||
pred = instr.getBlock().getAPredecessor() and
|
||||
not exists(PhiOperand operand |
|
||||
not exists(PhiInputOperand operand |
|
||||
operand = instr.getAnOperand() and
|
||||
operand.getPredecessorBlock() = pred
|
||||
)
|
||||
@@ -153,7 +153,7 @@ module InstructionSanity {
|
||||
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
|
||||
operand.getUseInstruction() = instr and
|
||||
operand.getDefinitionInstruction() = defInstr and
|
||||
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
|
||||
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,10 +174,10 @@ module InstructionSanity {
|
||||
*
|
||||
* This check ensures we don't have too _few_ back edges.
|
||||
*/
|
||||
query predicate containsLoopOfForwardEdges(FunctionIR f) {
|
||||
query predicate containsLoopOfForwardEdges(IRFunction f) {
|
||||
exists(IRBlock block |
|
||||
forwardEdge+(block, block) and
|
||||
block.getEnclosingFunctionIR() = f
|
||||
block.getEnclosingIRFunction() = f
|
||||
)
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ module InstructionSanity {
|
||||
* This check ensures we don't have too _many_ back edges.
|
||||
*/
|
||||
query predicate lostReachability(IRBlock block) {
|
||||
exists(FunctionIR f, IRBlock entry |
|
||||
exists(IRFunction f, IRBlock entry |
|
||||
entry = f.getEntryBlock() and
|
||||
entry.getASuccessor+() = block and
|
||||
not forwardEdge+(entry, block) and
|
||||
@@ -373,14 +373,14 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getEnclosingFunction() {
|
||||
result = getEnclosingFunctionIR().getFunction()
|
||||
result = getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
* Gets the IRFunction object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = Construction::getInstructionEnclosingIRFunction(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1622,15 +1622,22 @@ class PhiInstruction extends Instruction {
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
|
||||
*/
|
||||
final PhiInputOperand getAnInputOperand() {
|
||||
result = this.getAnOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that defines the input to one of the operands of this
|
||||
* instruction. It's possible for more than one operand to have the same
|
||||
* defining instruction, so this predicate will have the same number of
|
||||
* results as `getAnOperand()` or fewer.
|
||||
* results as `getAnInputOperand()` or fewer.
|
||||
*/
|
||||
pragma[noinline]
|
||||
final Instruction getAnOperandDefinitionInstruction() {
|
||||
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
|
||||
final Instruction getAnInput() {
|
||||
result = this.getAnInputOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ class Operand extends TOperand {
|
||||
result = getUseInstruction().getLocation()
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getUseInstruction().getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getUseInstruction().getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,12 +379,12 @@ class SideEffectOperand extends TypedOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
|
||||
PhiOperand() {
|
||||
PhiInputOperand() {
|
||||
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableFunctionIR(FunctionIR funcIR) {
|
||||
shouldPrintFunction(funcIR.getFunction())
|
||||
TPrintableIRFunction(IRFunction irFunc) {
|
||||
shouldPrintFunction(irFunc.getFunction())
|
||||
} or
|
||||
TPrintableIRBlock(IRBlock block) {
|
||||
shouldPrintFunction(block.getEnclosingFunction())
|
||||
@@ -113,30 +113,30 @@ abstract class PrintableIRNode extends TPrintableIRNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* An IR graph node representing a `FunctionIR` object.
|
||||
* An IR graph node representing a `IRFunction` object.
|
||||
*/
|
||||
class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
FunctionIR funcIR;
|
||||
class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
|
||||
IRFunction irFunc;
|
||||
|
||||
PrintableFunctionIR() {
|
||||
this = TPrintableFunctionIR(funcIR)
|
||||
PrintableIRFunction() {
|
||||
this = TPrintableIRFunction(irFunc)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = funcIR.toString()
|
||||
result = irFunc.toString()
|
||||
}
|
||||
|
||||
override Location getLocation() {
|
||||
result = funcIR.getLocation()
|
||||
result = irFunc.getLocation()
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
result = getIdentityString(irFunc.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
this = rank[result + 1](PrintableFunctionIR orderedFunc, Location location |
|
||||
location = orderedFunc.getFunctionIR().getLocation() |
|
||||
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
|
||||
location = orderedFunc.getIRFunction().getLocation() |
|
||||
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), orderedFunc.getLabel()
|
||||
)
|
||||
@@ -146,8 +146,8 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
none()
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
final IRFunction getIRFunction() {
|
||||
result = irFunc
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,8 +185,8 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
|
||||
any()
|
||||
}
|
||||
|
||||
override final PrintableFunctionIR getParent() {
|
||||
result.getFunctionIR() = block.getEnclosingFunctionIR()
|
||||
override final PrintableIRFunction getParent() {
|
||||
result.getIRFunction() = block.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
override string getProperty(string key) {
|
||||
|
||||
@@ -10,8 +10,8 @@ int getConstantValue(Instruction instr) {
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
|
||||
result = max(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pragma[noinline]
|
||||
int getConstantValueToPhi(Instruction def) {
|
||||
exists(PhiInstruction phi |
|
||||
result = getConstantValue(def) and
|
||||
def = phi.getAnOperandDefinitionInstruction()
|
||||
def = phi.getAnInput()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,38 +19,38 @@ class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||
}
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
variableAddressValueNumber(_, funcIR, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeParameterValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
initializeParameterValueNumber(_, funcIR, var)
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(FunctionIR funcIR) {
|
||||
initializeThisValueNumber(_, funcIR)
|
||||
TInitializeThisValueNumber(IRFunction irFunc) {
|
||||
initializeThisValueNumber(_, irFunc)
|
||||
} or
|
||||
TConstantValueNumber(FunctionIR funcIR, Type type, string value) {
|
||||
constantValueNumber(_, funcIR, type, value)
|
||||
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
|
||||
constantValueNumber(_, irFunc, type, value)
|
||||
} or
|
||||
TFieldAddressValueNumber(FunctionIR funcIR, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, funcIR, field, objectAddress)
|
||||
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
TBinaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
binaryValueNumber(_, funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(FunctionIR funcIR, Opcode opcode, Type type, int elementSize,
|
||||
TPointerArithmeticValueNumber(IRFunction irFunc, Opcode opcode, Type type, int elementSize,
|
||||
ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
pointerArithmeticValueNumber(_, funcIR, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, funcIR, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
|
||||
TInheritanceConversionValueNumber(IRFunction irFunc, Opcode opcode, Class baseClass,
|
||||
Class derivedClass, ValueNumber operand) {
|
||||
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
|
||||
inheritanceConversionValueNumber(_, irFunc, opcode, baseClass, derivedClass, operand)
|
||||
} or
|
||||
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
|
||||
uniqueValueNumber(instr, funcIR)
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) {
|
||||
uniqueValueNumber(instr, irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,39 +134,39 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, IRFunction irFunc,
|
||||
IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
|
||||
FunctionIR funcIR, IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, IRVariable var) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
|
||||
private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFunc, Type type,
|
||||
string value) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
|
||||
Field field, ValueNumber objectAddress) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
valueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof PointerArithmeticInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -175,9 +175,9 @@ private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR,
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
@@ -185,9 +185,9 @@ private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction inst
|
||||
valueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -195,8 +195,8 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
|
||||
}
|
||||
|
||||
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getBaseClass() = baseClass and
|
||||
instr.getDerivedClass() = derivedClass and
|
||||
@@ -207,8 +207,8 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
|
||||
* Holds if `instr` should be assigned a unique value number because this library does not know how
|
||||
* to determine if two instances of that instruction are equivalent.
|
||||
*/
|
||||
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr.getResultType() instanceof VoidType) and
|
||||
not numberableInstruction(instr)
|
||||
}
|
||||
@@ -218,9 +218,9 @@ private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
*/
|
||||
cached ValueNumber valueNumber(Instruction instr) {
|
||||
result = nonUniqueValueNumber(instr) or
|
||||
exists(FunctionIR funcIR |
|
||||
uniqueValueNumber(instr, funcIR) and
|
||||
result = TUniqueValueNumber(funcIR, instr)
|
||||
exists(IRFunction irFunc |
|
||||
uniqueValueNumber(instr, irFunc) and
|
||||
result = TUniqueValueNumber(irFunc, instr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -236,47 +236,47 @@ ValueNumber valueNumberOfOperand(Operand op) {
|
||||
* value number.
|
||||
*/
|
||||
private ValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(FunctionIR funcIR |
|
||||
funcIR = instr.getEnclosingFunctionIR() and
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, funcIR, var) and
|
||||
result = TVariableAddressValueNumber(funcIR, var)
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
) or
|
||||
exists(IRVariable var |
|
||||
initializeParameterValueNumber(instr, funcIR, var) and
|
||||
result = TInitializeParameterValueNumber(funcIR, var)
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
) or
|
||||
(
|
||||
initializeThisValueNumber(instr, funcIR) and
|
||||
result = TInitializeThisValueNumber(funcIR)
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
) or
|
||||
exists(Type type, string value |
|
||||
constantValueNumber(instr, funcIR, type, value) and
|
||||
result = TConstantValueNumber(funcIR, type, value)
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
) or
|
||||
exists(Field field, ValueNumber objectAddress |
|
||||
fieldAddressValueNumber(instr, funcIR, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(funcIR, field, objectAddress)
|
||||
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber leftOperand, ValueNumber rightOperand |
|
||||
binaryValueNumber(instr, funcIR, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber operand |
|
||||
unaryValueNumber(instr, funcIR, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(funcIR, opcode, type, operand)
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
|
||||
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
|
||||
inheritanceConversionValueNumber(instr, irFunc, opcode, baseClass, derivedClass,
|
||||
operand) and
|
||||
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
result = TPointerArithmeticValueNumber(funcIR, opcode, type, elementSize, leftOperand,
|
||||
result = TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand)
|
||||
) or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
|
||||
@@ -190,7 +190,7 @@ cached private module Cached {
|
||||
.hasInstruction(result, getInstructionTag(instruction), _, _)
|
||||
}
|
||||
|
||||
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
|
||||
cached IRFunction getInstructionEnclosingIRFunction(Instruction instruction) {
|
||||
result.getFunction() = getInstructionTranslatedElement(instruction).getFunction()
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ private IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
|
||||
}
|
||||
|
||||
private predicate isBlockReachable(IRBlock block) {
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
getAFeasiblePredecessorBlock*(block) = f.getEntryBlock()
|
||||
)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class ReachableInstruction extends Instruction {
|
||||
|
||||
module Graph {
|
||||
predicate isEntryBlock(ReachableBlock block) {
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
block = f.getEntryBlock()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import Instruction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
|
||||
@@ -63,8 +63,8 @@ class IRBlockBase extends TIRBlock {
|
||||
result = getInstructionCount(this)
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getFirstInstruction(this).getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
final Function getEnclosingFunction() {
|
||||
@@ -116,7 +116,7 @@ class IRBlock extends IRBlockBase {
|
||||
* Holds if this block is reachable from the entry point of its function
|
||||
*/
|
||||
final predicate isReachableFromFunctionEntry() {
|
||||
this = getEnclosingFunctionIR().getEntryBlock() or
|
||||
this = getEnclosingIRFunction().getEntryBlock() or
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@ private import internal.IRInternal
|
||||
import Instruction
|
||||
import cpp
|
||||
|
||||
private newtype TFunctionIR =
|
||||
MkFunctionIR(Function func) {
|
||||
private newtype TIRFunction =
|
||||
MkIRFunction(Function func) {
|
||||
Construction::functionHasIR(func)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the IR for a function.
|
||||
*/
|
||||
class FunctionIR extends TFunctionIR {
|
||||
class IRFunction extends TIRFunction {
|
||||
Function func;
|
||||
|
||||
FunctionIR() {
|
||||
this = MkFunctionIR(func)
|
||||
IRFunction() {
|
||||
this = MkIRFunction(func)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final ReturnInstruction getReturnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
|
||||
*/
|
||||
pragma[noinline]
|
||||
final IRReturnVariable getReturnVariable() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
|
||||
* Gets all instructions in this function.
|
||||
*/
|
||||
final Instruction getAnInstruction() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all blocks in this function.
|
||||
*/
|
||||
final IRBlock getABlock() {
|
||||
result.getEnclosingFunctionIR() = this
|
||||
result.getEnclosingIRFunction() = this
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.TempVariableTag
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
@@ -48,7 +48,7 @@ abstract class IRVariable extends TIRVariable {
|
||||
/**
|
||||
* Gets the IR for the function that references this variable.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result.getFunction() = func
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.IRInternal
|
||||
import FunctionIR
|
||||
import IRFunction
|
||||
import IRBlock
|
||||
import IRVariable
|
||||
import Operand
|
||||
@@ -15,7 +15,7 @@ module InstructionSanity {
|
||||
/**
|
||||
* Holds if the instruction `instr` should be expected to have an operand
|
||||
* with operand tag `tag`. Only holds for singleton operand tags. Tags with
|
||||
* parameters, such as `PhiOperand` and `PositionalArgumentOperand` are handled
|
||||
* parameters, such as `PhiInputOperand` and `PositionalArgumentOperand` are handled
|
||||
* separately in `unexpectedOperand`.
|
||||
*/
|
||||
private predicate expectsOperand(Instruction instr, OperandTag tag) {
|
||||
@@ -87,7 +87,7 @@ module InstructionSanity {
|
||||
*/
|
||||
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
|
||||
pred = instr.getBlock().getAPredecessor() and
|
||||
not exists(PhiOperand operand |
|
||||
not exists(PhiInputOperand operand |
|
||||
operand = instr.getAnOperand() and
|
||||
operand.getPredecessorBlock() = pred
|
||||
)
|
||||
@@ -153,7 +153,7 @@ module InstructionSanity {
|
||||
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
|
||||
operand.getUseInstruction() = instr and
|
||||
operand.getDefinitionInstruction() = defInstr and
|
||||
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
|
||||
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,10 +174,10 @@ module InstructionSanity {
|
||||
*
|
||||
* This check ensures we don't have too _few_ back edges.
|
||||
*/
|
||||
query predicate containsLoopOfForwardEdges(FunctionIR f) {
|
||||
query predicate containsLoopOfForwardEdges(IRFunction f) {
|
||||
exists(IRBlock block |
|
||||
forwardEdge+(block, block) and
|
||||
block.getEnclosingFunctionIR() = f
|
||||
block.getEnclosingIRFunction() = f
|
||||
)
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ module InstructionSanity {
|
||||
* This check ensures we don't have too _many_ back edges.
|
||||
*/
|
||||
query predicate lostReachability(IRBlock block) {
|
||||
exists(FunctionIR f, IRBlock entry |
|
||||
exists(IRFunction f, IRBlock entry |
|
||||
entry = f.getEntryBlock() and
|
||||
entry.getASuccessor+() = block and
|
||||
not forwardEdge+(entry, block) and
|
||||
@@ -373,14 +373,14 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getEnclosingFunction() {
|
||||
result = getEnclosingFunctionIR().getFunction()
|
||||
result = getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
* Gets the IRFunction object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = Construction::getInstructionEnclosingIRFunction(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1622,15 +1622,22 @@ class PhiInstruction extends Instruction {
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
|
||||
*/
|
||||
final PhiInputOperand getAnInputOperand() {
|
||||
result = this.getAnOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that defines the input to one of the operands of this
|
||||
* instruction. It's possible for more than one operand to have the same
|
||||
* defining instruction, so this predicate will have the same number of
|
||||
* results as `getAnOperand()` or fewer.
|
||||
* results as `getAnInputOperand()` or fewer.
|
||||
*/
|
||||
pragma[noinline]
|
||||
final Instruction getAnOperandDefinitionInstruction() {
|
||||
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
|
||||
final Instruction getAnInput() {
|
||||
result = this.getAnInputOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ class Operand extends TOperand {
|
||||
result = getUseInstruction().getLocation()
|
||||
}
|
||||
|
||||
final FunctionIR getEnclosingFunctionIR() {
|
||||
result = getUseInstruction().getEnclosingFunctionIR()
|
||||
final IRFunction getEnclosingIRFunction() {
|
||||
result = getUseInstruction().getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,12 +379,12 @@ class SideEffectOperand extends TypedOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
|
||||
PhiOperand() {
|
||||
PhiInputOperand() {
|
||||
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableFunctionIR(FunctionIR funcIR) {
|
||||
shouldPrintFunction(funcIR.getFunction())
|
||||
TPrintableIRFunction(IRFunction irFunc) {
|
||||
shouldPrintFunction(irFunc.getFunction())
|
||||
} or
|
||||
TPrintableIRBlock(IRBlock block) {
|
||||
shouldPrintFunction(block.getEnclosingFunction())
|
||||
@@ -113,30 +113,30 @@ abstract class PrintableIRNode extends TPrintableIRNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* An IR graph node representing a `FunctionIR` object.
|
||||
* An IR graph node representing a `IRFunction` object.
|
||||
*/
|
||||
class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
FunctionIR funcIR;
|
||||
class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
|
||||
IRFunction irFunc;
|
||||
|
||||
PrintableFunctionIR() {
|
||||
this = TPrintableFunctionIR(funcIR)
|
||||
PrintableIRFunction() {
|
||||
this = TPrintableIRFunction(irFunc)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = funcIR.toString()
|
||||
result = irFunc.toString()
|
||||
}
|
||||
|
||||
override Location getLocation() {
|
||||
result = funcIR.getLocation()
|
||||
result = irFunc.getLocation()
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
result = getIdentityString(irFunc.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
this = rank[result + 1](PrintableFunctionIR orderedFunc, Location location |
|
||||
location = orderedFunc.getFunctionIR().getLocation() |
|
||||
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
|
||||
location = orderedFunc.getIRFunction().getLocation() |
|
||||
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), orderedFunc.getLabel()
|
||||
)
|
||||
@@ -146,8 +146,8 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
none()
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
final IRFunction getIRFunction() {
|
||||
result = irFunc
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,8 +185,8 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
|
||||
any()
|
||||
}
|
||||
|
||||
override final PrintableFunctionIR getParent() {
|
||||
result.getFunctionIR() = block.getEnclosingFunctionIR()
|
||||
override final PrintableIRFunction getParent() {
|
||||
result.getIRFunction() = block.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
override string getProperty(string key) {
|
||||
|
||||
@@ -10,8 +10,8 @@ int getConstantValue(Instruction instr) {
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
|
||||
result = max(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def)) and
|
||||
result = min(Instruction def | def = phi.getAnInput() | getConstantValueToPhi(def))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pragma[noinline]
|
||||
int getConstantValueToPhi(Instruction def) {
|
||||
exists(PhiInstruction phi |
|
||||
result = getConstantValue(def) and
|
||||
def = phi.getAnOperandDefinitionInstruction()
|
||||
def = phi.getAnInput()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,38 +19,38 @@ class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||
}
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
variableAddressValueNumber(_, funcIR, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeParameterValueNumber(FunctionIR funcIR, IRVariable var) {
|
||||
initializeParameterValueNumber(_, funcIR, var)
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(FunctionIR funcIR) {
|
||||
initializeThisValueNumber(_, funcIR)
|
||||
TInitializeThisValueNumber(IRFunction irFunc) {
|
||||
initializeThisValueNumber(_, irFunc)
|
||||
} or
|
||||
TConstantValueNumber(FunctionIR funcIR, Type type, string value) {
|
||||
constantValueNumber(_, funcIR, type, value)
|
||||
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
|
||||
constantValueNumber(_, irFunc, type, value)
|
||||
} or
|
||||
TFieldAddressValueNumber(FunctionIR funcIR, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, funcIR, field, objectAddress)
|
||||
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
TBinaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
binaryValueNumber(_, funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(FunctionIR funcIR, Opcode opcode, Type type, int elementSize,
|
||||
TPointerArithmeticValueNumber(IRFunction irFunc, Opcode opcode, Type type, int elementSize,
|
||||
ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
pointerArithmeticValueNumber(_, funcIR, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, funcIR, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
|
||||
TInheritanceConversionValueNumber(IRFunction irFunc, Opcode opcode, Class baseClass,
|
||||
Class derivedClass, ValueNumber operand) {
|
||||
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
|
||||
inheritanceConversionValueNumber(_, irFunc, opcode, baseClass, derivedClass, operand)
|
||||
} or
|
||||
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
|
||||
uniqueValueNumber(instr, funcIR)
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) {
|
||||
uniqueValueNumber(instr, irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,39 +134,39 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate variableAddressValueNumber(VariableAddressInstruction instr, IRFunction irFunc,
|
||||
IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
|
||||
FunctionIR funcIR, IRVariable var) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, IRVariable var) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getVariable() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
|
||||
private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFunc, Type type,
|
||||
string value) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
|
||||
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
|
||||
Field field, ValueNumber objectAddress) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
valueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate binaryValueNumber(BinaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof PointerArithmeticInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -175,9 +175,9 @@ private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR,
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
@@ -185,9 +185,9 @@ private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction inst
|
||||
valueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
|
||||
private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Opcode opcode,
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
@@ -195,8 +195,8 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
|
||||
}
|
||||
|
||||
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
|
||||
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getBaseClass() = baseClass and
|
||||
instr.getDerivedClass() = derivedClass and
|
||||
@@ -207,8 +207,8 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
|
||||
* Holds if `instr` should be assigned a unique value number because this library does not know how
|
||||
* to determine if two instances of that instruction are equivalent.
|
||||
*/
|
||||
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
instr.getEnclosingFunctionIR() = funcIR and
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr.getResultType() instanceof VoidType) and
|
||||
not numberableInstruction(instr)
|
||||
}
|
||||
@@ -218,9 +218,9 @@ private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
|
||||
*/
|
||||
cached ValueNumber valueNumber(Instruction instr) {
|
||||
result = nonUniqueValueNumber(instr) or
|
||||
exists(FunctionIR funcIR |
|
||||
uniqueValueNumber(instr, funcIR) and
|
||||
result = TUniqueValueNumber(funcIR, instr)
|
||||
exists(IRFunction irFunc |
|
||||
uniqueValueNumber(instr, irFunc) and
|
||||
result = TUniqueValueNumber(irFunc, instr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -236,47 +236,47 @@ ValueNumber valueNumberOfOperand(Operand op) {
|
||||
* value number.
|
||||
*/
|
||||
private ValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(FunctionIR funcIR |
|
||||
funcIR = instr.getEnclosingFunctionIR() and
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, funcIR, var) and
|
||||
result = TVariableAddressValueNumber(funcIR, var)
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
) or
|
||||
exists(IRVariable var |
|
||||
initializeParameterValueNumber(instr, funcIR, var) and
|
||||
result = TInitializeParameterValueNumber(funcIR, var)
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
) or
|
||||
(
|
||||
initializeThisValueNumber(instr, funcIR) and
|
||||
result = TInitializeThisValueNumber(funcIR)
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
) or
|
||||
exists(Type type, string value |
|
||||
constantValueNumber(instr, funcIR, type, value) and
|
||||
result = TConstantValueNumber(funcIR, type, value)
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
) or
|
||||
exists(Field field, ValueNumber objectAddress |
|
||||
fieldAddressValueNumber(instr, funcIR, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(funcIR, field, objectAddress)
|
||||
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber leftOperand, ValueNumber rightOperand |
|
||||
binaryValueNumber(instr, funcIR, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(funcIR, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, ValueNumber operand |
|
||||
unaryValueNumber(instr, funcIR, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(funcIR, opcode, type, operand)
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
|
||||
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
|
||||
inheritanceConversionValueNumber(instr, irFunc, opcode, baseClass, derivedClass,
|
||||
operand) and
|
||||
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
) or
|
||||
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
|
||||
ValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
result = TPointerArithmeticValueNumber(funcIR, opcode, type, elementSize, leftOperand,
|
||||
result = TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand)
|
||||
) or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
|
||||
@@ -73,7 +73,7 @@ private predicate operandEscapesDomain(Operand operand) {
|
||||
not isArgumentForParameter(_, operand, _) and
|
||||
not isOnlyEscapesViaReturnArgument(operand) and
|
||||
not operand.getUseInstruction() instanceof ReturnValueInstruction and
|
||||
not operand instanceof PhiOperand
|
||||
not operand instanceof PhiInputOperand
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,7 @@ private predicate operandEscapesNonReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUseInstruction())
|
||||
or
|
||||
operand instanceof PhiOperand and
|
||||
operand instanceof PhiInputOperand and
|
||||
resultEscapesNonReturn(operand.getUseInstruction())
|
||||
or
|
||||
operandEscapesDomain(operand)
|
||||
@@ -194,7 +194,7 @@ private predicate operandMayReachReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUseInstruction())
|
||||
or
|
||||
operand instanceof PhiOperand and
|
||||
operand instanceof PhiInputOperand and
|
||||
resultMayReachReturn(operand.getUseInstruction())
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ cached private module Cached {
|
||||
}
|
||||
|
||||
cached predicate functionHasIR(Function func) {
|
||||
exists(OldIR::FunctionIR funcIR |
|
||||
funcIR.getFunction() = func
|
||||
exists(OldIR::IRFunction irFunc |
|
||||
irFunc.getFunction() = func
|
||||
)
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ cached private module Cached {
|
||||
)
|
||||
)
|
||||
else (
|
||||
result = instruction.getEnclosingFunctionIR().getUnmodeledDefinitionInstruction()
|
||||
result = instruction.getEnclosingIRFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
) or
|
||||
// Connect any definitions that are not being modeled in SSA to the
|
||||
@@ -118,7 +118,7 @@ cached private module Cached {
|
||||
instruction = Chi(getOldInstruction(result)) and
|
||||
tag instanceof ChiPartialOperandTag
|
||||
or
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
tag instanceof UnmodeledUseOperandTag and
|
||||
result = f.getUnmodeledDefinitionInstruction() and
|
||||
instruction = f.getUnmodeledUseInstruction()
|
||||
@@ -301,7 +301,7 @@ cached private module Cached {
|
||||
result instanceof Opcode::Unreached
|
||||
}
|
||||
|
||||
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
|
||||
cached IRFunction getInstructionEnclosingIRFunction(Instruction instruction) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = WrappedInstruction(oldInstruction)
|
||||
or
|
||||
|
||||
@@ -25,7 +25,7 @@ private IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
|
||||
}
|
||||
|
||||
private predicate isBlockReachable(IRBlock block) {
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
getAFeasiblePredecessorBlock*(block) = f.getEntryBlock()
|
||||
)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class ReachableInstruction extends Instruction {
|
||||
|
||||
module Graph {
|
||||
predicate isEntryBlock(ReachableBlock block) {
|
||||
exists(FunctionIR f |
|
||||
exists(IRFunction f |
|
||||
block = f.getEntryBlock()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ private predicate boundedNonPhiOperand(NonPhiOperand op, Bound b, int delta, boo
|
||||
* - `upper = false` : `op2 >= op1 + delta`
|
||||
*/
|
||||
private predicate boundFlowStepPhi(
|
||||
PhiOperand op2, Operand op1, int delta, boolean upper, Reason reason
|
||||
PhiInputOperand op2, Operand op1, int delta, boolean upper, Reason reason
|
||||
) {
|
||||
op2.getDefinitionInstruction().(CopyInstruction).getSourceValueOperand() = op1 and
|
||||
(upper = true or upper = false) and
|
||||
@@ -393,7 +393,7 @@ private predicate boundFlowStepPhi(
|
||||
|
||||
|
||||
private predicate boundedPhiOperand(
|
||||
PhiOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta,
|
||||
PhiInputOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta,
|
||||
Reason reason
|
||||
) {
|
||||
exists(NonPhiOperand op2, int d1, int d2, Reason r1, Reason r2 |
|
||||
@@ -446,7 +446,7 @@ private predicate unequalOperand(Operand op, Bound b, int delta, Reason reason)
|
||||
|
||||
private predicate boundedPhiCandValidForEdge(
|
||||
PhiInstruction phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta,
|
||||
Reason reason, PhiOperand op
|
||||
Reason reason, PhiInputOperand op
|
||||
) {
|
||||
boundedPhiCand(phi, upper, b, delta, fromBackEdge, origdelta, reason) and
|
||||
(
|
||||
@@ -469,7 +469,7 @@ private int weakenDelta(boolean upper, int delta) {
|
||||
}
|
||||
|
||||
private predicate boundedPhiInp(
|
||||
PhiInstruction phi, PhiOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge,
|
||||
PhiInstruction phi, PhiInputOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge,
|
||||
int origdelta, Reason reason
|
||||
) {
|
||||
phi.getAnOperand() = op and
|
||||
@@ -499,12 +499,12 @@ private predicate boundedPhiInp(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate boundedPhiInp1(
|
||||
PhiInstruction phi, PhiOperand op, Bound b, int delta, boolean upper
|
||||
PhiInstruction phi, PhiInputOperand op, Bound b, int delta, boolean upper
|
||||
) {
|
||||
boundedPhiInp(phi, op, b, delta, upper, _, _, _)
|
||||
}
|
||||
|
||||
private predicate selfBoundedPhiInp(PhiInstruction phi, PhiOperand op, boolean upper) {
|
||||
private predicate selfBoundedPhiInp(PhiInstruction phi, PhiInputOperand op, boolean upper) {
|
||||
exists(int d, ValueNumberBound phibound |
|
||||
phibound.getInstruction() = phi and
|
||||
boundedPhiInp(phi, op, phibound, d, upper, _, _, _) and
|
||||
@@ -521,7 +521,7 @@ private predicate boundedPhiCand(
|
||||
PhiInstruction phi, boolean upper, Bound b, int delta, boolean fromBackEdge, int origdelta,
|
||||
Reason reason
|
||||
) {
|
||||
exists(PhiOperand op |
|
||||
exists(PhiInputOperand op |
|
||||
boundedPhiInp(phi, op, b, delta, upper, fromBackEdge, origdelta, reason)
|
||||
)
|
||||
}
|
||||
@@ -556,7 +556,7 @@ private predicate boundedInstruction(
|
||||
Instruction i, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, Reason reason
|
||||
) {
|
||||
i instanceof PhiInstruction and
|
||||
forex(PhiOperand op | op = i.getAnOperand() |
|
||||
forex(PhiInputOperand op | op = i.getAnOperand() |
|
||||
boundedPhiCandValidForEdge(i, b, delta, upper, fromBackEdge, origdelta, reason, op)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -22,8 +22,8 @@ IntValue getConstantValue(Instruction instr) {
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
|
||||
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
|
||||
result = max(PhiInputOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
|
||||
result = min(PhiInputOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ predicate valueFlowStep(Instruction i, Operand op, int delta) {
|
||||
)
|
||||
}
|
||||
|
||||
predicate backEdge(PhiInstruction phi, PhiOperand op) {
|
||||
predicate backEdge(PhiInstruction phi, PhiInputOperand op) {
|
||||
phi.getAnOperand() = op and
|
||||
phi.getBlock() = op.getPredecessorBlock().getBackEdgeSuccessor(_)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user