Merge pull request #899 from Semmle/rdmarsh/cpp/IRRename-rebased

C++: Rename a few problematic IR APIs
This commit is contained in:
Robert Marsh
2019-02-07 09:28:59 -08:00
committed by GitHub
37 changed files with 703 additions and 418 deletions

View File

@@ -276,7 +276,7 @@ class IRGuardCondition extends Instruction {
this.controlsBlock(controlled, testIsTrue)
or
exists (IRGuardCondition ne
| this = ne.(LogicalNotInstruction).getOperand() and
| this = ne.(LogicalNotInstruction).getUnary() and
ne.controls(controlled, testIsTrue.booleanNot()))
}
@@ -359,7 +359,7 @@ private predicate is_condition(Instruction guard) {
branch.getCondition() = guard
)
or
exists(LogicalNotInstruction cond | is_condition(cond) and cond.getOperand() = guard)
exists(LogicalNotInstruction cond | is_condition(cond) and cond.getUnary() = guard)
}
/**
@@ -383,15 +383,15 @@ private predicate compares_eq(Instruction test, Operand left, Operand right, int
or
/* (x is true => (left == right + k)) => (!x is false => (left == right + k)) */
exists(boolean isFalse | testIsTrue = isFalse.booleanNot() |
compares_eq(test.(LogicalNotInstruction).getOperand(), left, right, k, areEqual, isFalse)
compares_eq(test.(LogicalNotInstruction).getUnary(), left, right, k, areEqual, isFalse)
)
}
/** Rearrange various simple comparisons into `left == right + k` form. */
private predicate simple_comparison_eq(CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual) {
left = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareEQInstruction and right = cmp.getAnOperand().(RightOperand) and k = 0 and areEqual = true
left = cmp.getLeftOperand() and cmp instanceof CompareEQInstruction and right = cmp.getRightOperand() and k = 0 and areEqual = true
or
left = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareNEInstruction and right = cmp.getAnOperand().(RightOperand) and k = 0 and areEqual = false
left = cmp.getLeftOperand() and cmp instanceof CompareNEInstruction and right = cmp.getRightOperand() and k = 0 and areEqual = false
}
private predicate complex_eq(CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) {
@@ -421,7 +421,7 @@ private predicate compares_lt(Instruction test, Operand left, Operand right, int
or
/* (x is true => (left < right + k)) => (!x is false => (left < right + k)) */
exists(boolean isFalse | testIsTrue = isFalse.booleanNot() |
compares_lt(test.(LogicalNotInstruction).getOperand(), left, right, k, isLt, isFalse)
compares_lt(test.(LogicalNotInstruction).getUnary(), left, right, k, isLt, isFalse)
)
}
@@ -432,13 +432,13 @@ private predicate compares_ge(Instruction test, Operand left, Operand right, int
/** Rearrange various simple comparisons into `left < right + k` form. */
private predicate simple_comparison_lt(CompareInstruction cmp, Operand left, Operand right, int k) {
left = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareLTInstruction and right = cmp.getAnOperand().(RightOperand) and k = 0
left = cmp.getLeftOperand() and cmp instanceof CompareLTInstruction and right = cmp.getRightOperand() and k = 0
or
left = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareLEInstruction and right = cmp.getAnOperand().(RightOperand) and k = 1
left = cmp.getLeftOperand() and cmp instanceof CompareLEInstruction and right = cmp.getRightOperand() and k = 1
or
right = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareGTInstruction and left = cmp.getAnOperand().(RightOperand) and k = 0
right = cmp.getLeftOperand() and cmp instanceof CompareGTInstruction and left = cmp.getRightOperand() and k = 0
or
right = cmp.getAnOperand().(LeftOperand) and cmp instanceof CompareGEInstruction and left = cmp.getAnOperand().(RightOperand) and k = 1
right = cmp.getLeftOperand() and cmp instanceof CompareGEInstruction and left = cmp.getRightOperand() and k = 1
}
private predicate complex_lt(CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue) {
@@ -452,12 +452,12 @@ private predicate complex_lt(CompareInstruction cmp, Operand left, Operand right
left < (right - x) + c => left < right + (c-x) */
private predicate sub_lt(CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue) {
exists(SubInstruction lhs, int c, int x | compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
left = lhs.getAnOperand().(LeftOperand) and x = int_value(lhs.getRightOperand())
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
and k = c + x
)
or
exists(SubInstruction rhs, int c, int x | compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
right = rhs.getAnOperand().(LeftOperand) and x = int_value(rhs.getRightOperand())
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
and k = c - x
)
}
@@ -466,17 +466,17 @@ private predicate sub_lt(CompareInstruction cmp, Operand left, Operand right, in
left < (right + x) + c => left < right + (c+x) */
private predicate add_lt(CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue) {
exists(AddInstruction lhs, int c, int x | compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
(left = lhs.getAnOperand().(LeftOperand) and x = int_value(lhs.getRightOperand())
(left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
or
left = lhs.getAnOperand().(RightOperand) and x = int_value(lhs.getLeftOperand())
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
)
and k = c - x
)
or
exists(AddInstruction rhs, int c, int x | compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
(right = rhs.getAnOperand().(LeftOperand) and x = int_value(rhs.getRightOperand())
(right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
or
right = rhs.getAnOperand().(RightOperand) and x = int_value(rhs.getLeftOperand())
right = rhs.getRightOperand() and x = int_value(rhs.getLeft())
)
and k = c + x
)
@@ -487,12 +487,12 @@ private predicate add_lt(CompareInstruction cmp, Operand left, Operand right, in
left == (right - x) + c => left == right + (c-x) */
private predicate sub_eq(CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) {
exists(SubInstruction lhs, int c, int x | compares_eq(cmp, lhs.getAUse(), right, c, areEqual, testIsTrue) and
left = lhs.getAnOperand().(LeftOperand) and x = int_value(lhs.getRightOperand())
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
and k = c + x
)
or
exists(SubInstruction rhs, int c, int x | compares_eq(cmp, left, rhs.getAUse(), c, areEqual, testIsTrue) and
right = rhs.getAnOperand().(LeftOperand) and x = int_value(rhs.getRightOperand())
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
and k = c - x
)
}
@@ -502,17 +502,17 @@ private predicate sub_eq(CompareInstruction cmp, Operand left, Operand right, in
left == (right + x) + c => left == right + (c+x) */
private predicate add_eq(CompareInstruction cmp, Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) {
exists(AddInstruction lhs, int c, int x | compares_eq(cmp, lhs.getAUse(), right, c, areEqual, testIsTrue) and
(left = lhs.getAnOperand().(LeftOperand) and x = int_value(lhs.getRightOperand())
(left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
or
left = lhs.getAnOperand().(RightOperand) and x = int_value(lhs.getLeftOperand())
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
)
and k = c - x
)
or
exists(AddInstruction rhs, int c, int x | compares_eq(cmp, left, rhs.getAUse(), c, areEqual, testIsTrue) and
(right = rhs.getAnOperand().(LeftOperand) and x = int_value(rhs.getRightOperand())
(right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
or
right = rhs.getAnOperand().(RightOperand) and x = int_value(rhs.getLeftOperand())
right = rhs.getRightOperand() and x = int_value(rhs.getLeft())
)
and k = c + x
)

View File

@@ -16,7 +16,7 @@ class Node extends Instruction {
* INTERNAL: Do not use. Alternative name for `getFunction`.
*/
Function getEnclosingCallable() {
result = this.getFunction()
result = this.getEnclosingFunction()
}
/** Gets the type of this node. */
@@ -155,7 +155,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
nodeTo.(CopyInstruction).getSourceValue() = nodeFrom or
nodeTo.(PhiInstruction).getAnOperand().getDefinitionInstruction() = nodeFrom or
// Treat all conversions as flow, even conversions between different numeric types.
nodeTo.(ConvertInstruction).getOperand() = nodeFrom
nodeTo.(ConvertInstruction).getUnary() = nodeFrom
}
/**

View File

@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
* Gets all instructions in this function.
*/
final Instruction getAnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
* Gets all blocks in this function.
*/
final IRBlock getABlock() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
}

View File

@@ -33,7 +33,7 @@ class IRBlockBase extends TIRBlock {
*/
int getDisplayIndex() {
this = rank[result + 1](IRBlock funcBlock |
funcBlock.getFunction() = getFunction() |
funcBlock.getEnclosingFunction() = getEnclosingFunction() |
funcBlock order by funcBlock.getUniqueId()
)
}
@@ -63,12 +63,12 @@ class IRBlockBase extends TIRBlock {
result = strictcount(getInstruction(_))
}
final FunctionIR getFunctionIR() {
result = getFirstInstruction(this).getFunctionIR()
final FunctionIR getEnclosingFunctionIR() {
result = getFirstInstruction(this).getEnclosingFunctionIR()
}
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
final Function getEnclosingFunction() {
result = getFirstInstruction(this).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 = getFunctionIR().getEntryBlock() or
this = getEnclosingFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -7,7 +7,7 @@ private import semmle.code.cpp.ir.internal.TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
result.getVariable() = var and
result.getFunction() = func
result.getEnclosingFunction() = func
}
/**
@@ -47,14 +47,14 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the IR for the function that references this variable.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result.getFunction() = func
}
/**
* Gets the function that references this variable.
*/
final Function getFunction() {
final Function getEnclosingFunction() {
result = func
}
}

View File

@@ -123,7 +123,7 @@ module InstructionSanity {
query predicate unexplainedLoop(Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getFunction() = f and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
@@ -143,9 +143,9 @@ module InstructionSanity {
* a different function.
*/
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
operand.getInstruction() = instr and
operand.getUseInstruction() = instr and
operand.getDefinitionInstruction() = defInstr and
instr.getFunctionIR() != defInstr.getFunctionIR()
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
}
/**
@@ -169,7 +169,7 @@ module InstructionSanity {
query predicate containsLoopOfForwardEdges(FunctionIR f) {
exists(IRBlock block |
forwardEdge+(block, block) and
block.getFunctionIR() = f
block.getEnclosingFunctionIR() = f
)
}
@@ -196,10 +196,10 @@ module InstructionSanity {
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
fromBlock = count(IRBlock b1, IRBlock b2 |
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
b1.getEnclosingFunction() = f and b1.getBackEdgeSuccessor(_) = b2
) and
fromInstr != fromBlock
}
@@ -364,14 +364,14 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getFunction() {
result = getFunctionIR().getFunction()
final Function getEnclosingFunction() {
result = getEnclosingFunctionIR().getFunction()
}
/**
* Gets the FunctionIR object that contains the IR for this instruction.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result = Construction::getInstructionEnclosingFunctionIR(this)
}
@@ -472,7 +472,7 @@ class Instruction extends Construction::TInstruction {
* Gets all of this instruction's operands.
*/
final Operand getAnOperand() {
result.getInstruction() = this
result.getUseInstruction() = this
}
/**
@@ -665,8 +665,12 @@ class FieldAddressInstruction extends FieldInstruction {
getOpcode() instanceof Opcode::FieldAddress
}
final UnaryOperand getObjectAddressOperand() {
result = getAnOperand()
}
final Instruction getObjectAddress() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
result = getObjectAddressOperand().getDefinitionInstruction()
}
}
@@ -710,8 +714,12 @@ class ReturnValueInstruction extends ReturnInstruction {
getOpcode() instanceof Opcode::ReturnValue
}
final ReturnValueOperand getReturnValueOperand() {
result = getAnOperand()
}
final Instruction getReturnValue() {
result = getAnOperand().(ReturnValueOperand).getDefinitionInstruction()
result = getReturnValueOperand().getDefinitionInstruction()
}
}
@@ -720,8 +728,12 @@ class CopyInstruction extends Instruction {
getOpcode() instanceof CopyOpcode
}
final CopySourceOperand getSourceValueOperand() {
result = getAnOperand()
}
final Instruction getSourceValue() {
result = getAnOperand().(CopySourceOperand).getDefinitionInstruction()
result = getSourceValueOperand().getDefinitionInstruction()
}
}
@@ -736,8 +748,12 @@ class LoadInstruction extends CopyInstruction {
getOpcode() instanceof Opcode::Load
}
final AddressOperand getSourceAddressOperand() {
result = getAnOperand()
}
final Instruction getSourceAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getSourceAddressOperand().getDefinitionInstruction()
}
}
@@ -750,8 +766,12 @@ class StoreInstruction extends CopyInstruction {
result instanceof IndirectMemoryAccess
}
final AddressOperand getDestinationAddressOperand() {
result = getAnOperand()
}
final Instruction getDestinationAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getDestinationAddressOperand().getDefinitionInstruction()
}
}
@@ -760,8 +780,12 @@ class ConditionalBranchInstruction extends Instruction {
getOpcode() instanceof Opcode::ConditionalBranch
}
final ConditionOperand getConditionOperand() {
result = getAnOperand()
}
final Instruction getCondition() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getConditionOperand().getDefinitionInstruction()
}
final Instruction getTrueSuccessor() {
@@ -818,21 +842,29 @@ class BinaryInstruction extends Instruction {
getOpcode() instanceof BinaryOpcode
}
final Instruction getLeftOperand() {
result = getAnOperand().(LeftOperand).getDefinitionInstruction()
final LeftOperand getLeftOperand() {
result = getAnOperand()
}
final RightOperand getRightOperand() {
result = getAnOperand()
}
final Instruction getRightOperand() {
result = getAnOperand().(RightOperand).getDefinitionInstruction()
final Instruction getLeft() {
result = getLeftOperand().getDefinitionInstruction()
}
final Instruction getRight() {
result = getRightOperand().getDefinitionInstruction()
}
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
op1 = getAnOperand().(LeftOperand) and op2 = getAnOperand().(RightOperand)
op1 = getLeftOperand() and op2 = getRightOperand()
or
op1 = getAnOperand().(RightOperand) and op2 = getAnOperand().(LeftOperand)
op1 = getRightOperand() and op2 = getLeftOperand()
}
}
@@ -948,8 +980,12 @@ class UnaryInstruction extends Instruction {
getOpcode() instanceof UnaryOpcode
}
final Instruction getOperand() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
final UnaryOperand getUnaryOperand() {
result = getAnOperand()
}
final Instruction getUnary() {
result = getUnaryOperand().getDefinitionInstruction()
}
}
@@ -1075,7 +1111,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Instruction getGreaterOperand() {
Instruction getGreater() {
none()
}
@@ -1085,7 +1121,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Instruction getLesserOperand() {
Instruction getLesser() {
none()
}
@@ -1102,12 +1138,12 @@ class CompareLTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLT
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1120,12 +1156,12 @@ class CompareGTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGT
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1138,12 +1174,12 @@ class CompareLEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLE
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1156,12 +1192,12 @@ class CompareGEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGE
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1174,8 +1210,12 @@ class SwitchInstruction extends Instruction {
getOpcode() instanceof Opcode::Switch
}
final ConditionOperand getExpressionOperand() {
result = getAnOperand()
}
final Instruction getExpression() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getExpressionOperand().getDefinitionInstruction()
}
final Instruction getACaseSuccessor() {
@@ -1197,38 +1237,63 @@ class CallInstruction extends Instruction {
getOpcode() instanceof Opcode::Call
}
/**
* Gets the operand the specifies the target function of the call.
*/
final CallTargetOperand getCallTargetOperand() {
result = getAnOperand()
}
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
final Instruction getCallTarget() {
result = getAnOperand().(CallTargetOperand).getDefinitionInstruction()
result = getCallTargetOperand().getDefinitionInstruction()
}
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
final ArgumentOperand getAnArgumentOperand() {
result = getAnOperand()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
final Instruction getAnArgument() {
result = getAnOperand().(ArgumentOperand).getDefinitionInstruction()
result = getAnArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
final ThisArgumentOperand getThisArgumentOperand() {
result = getAnOperand()
}
/**
* Gets the `this` pointer argument of the call, if any.
*/
final Instruction getThisArgument() {
result = getAnOperand().(ThisArgumentOperand).getDefinitionInstruction()
result = getThisArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the argument operand at the specified index.
*/
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
result = getAnOperand() and
result.getIndex() = index
}
/**
* Gets the argument at the specified index.
*/
final Instruction getPositionalArgument(int index) {
exists(PositionalArgumentOperand operand |
operand = getAnOperand() and
operand.getIndex() = index and
result = operand.getDefinitionInstruction()
)
result = getPositionalArgumentOperand(index).getDefinitionInstruction()
}
}
@@ -1337,6 +1402,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
BufferMayWriteSideEffectInstruction() {
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof BufferMayMemoryAccess
}
@@ -1359,18 +1425,32 @@ class ThrowValueInstruction extends ThrowInstruction {
getOpcode() instanceof Opcode::ThrowValue
}
/**
* Gets the address operand of the exception thrown by this instruction.
*/
final AddressOperand getExceptionAddressOperand() {
result = getAnOperand()
}
/**
* Gets the address of the exception thrown by this instruction.
*/
final Instruction getExceptionAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getExceptionAddressOperand().getDefinitionInstruction()
}
/**
* Gets the operand for the exception thrown by this instruction.
*/
final ExceptionOperand getExceptionOperand() {
result = getAnOperand()
}
/**
* Gets the exception thrown by this instruction.
*/
final Instruction getException() {
result = getAnOperand().(ExceptionOperand).getDefinitionInstruction()
result = getExceptionOperand().getDefinitionInstruction()
}
}
@@ -1552,15 +1632,30 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotalOperand() {
result = getAnOperand().(ChiTotalOperand).getDefinitionInstruction()
final ChiTotalOperand getTotalOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotal() {
result = getTotalOperand().getDefinitionInstruction()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartialOperand() {
result = getAnOperand().(ChiPartialOperand).getDefinitionInstruction()
final ChiPartialOperand getPartialOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() {
result = getPartialOperand().getDefinitionInstruction()
}
}

View File

@@ -6,11 +6,11 @@ import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import semmle.code.cpp.ir.internal.OperandTag
private newtype TOperand =
TNonPhiOperand(Instruction instr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(instr, tag)
TNonPhiOperand(Instruction useInstr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(useInstr, tag)
} or
TPhiOperand(PhiInstruction instr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(instr, predecessorBlock)
TPhiOperand(PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(useInstr, predecessorBlock)
}
/**
@@ -22,13 +22,13 @@ class Operand extends TOperand {
}
Location getLocation() {
result = getInstruction().getLocation()
result = getUseInstruction().getLocation()
}
/**
* Gets the `Instruction` that consumes this operand.
*/
Instruction getInstruction() {
Instruction getUseInstruction() {
none()
}
@@ -78,7 +78,7 @@ class Operand extends TOperand {
*/
final AddressOperand getAddressOperand() {
getMemoryAccess() instanceof IndirectMemoryAccess and
result.getInstruction() = getInstruction()
result.getUseInstruction() = getUseInstruction()
}
}
@@ -94,7 +94,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
this = TNonPhiOperand(instr, tag, defInstr)
}
override final Instruction getInstruction() {
override final Instruction getUseInstruction() {
result = instr
}
@@ -353,20 +353,20 @@ class SideEffectOperand extends NonPhiOperand {
* An operand of a `PhiInstruction`.
*/
class PhiOperand extends Operand, TPhiOperand {
PhiInstruction instr;
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
PhiOperand() {
this = TPhiOperand(instr, defInstr, predecessorBlock)
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
}
override string toString() {
result = "Phi"
}
override final PhiInstruction getInstruction() {
result = instr
override final PhiInstruction getUseInstruction() {
result = useInstr
}
override final Instruction getDefinitionInstruction() {

View File

@@ -53,10 +53,10 @@ private newtype TPrintableIRNode =
shouldPrintFunction(funcIR.getFunction())
} or
TPrintableIRBlock(IRBlock block) {
shouldPrintFunction(block.getFunction())
shouldPrintFunction(block.getEnclosingFunction())
} or
TPrintableInstruction(Instruction instr) {
shouldPrintFunction(instr.getFunction())
shouldPrintFunction(instr.getEnclosingFunction())
}
/**
@@ -185,7 +185,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
}
override final PrintableFunctionIR getParent() {
result.getFunctionIR() = block.getFunctionIR()
result.getFunctionIR() = block.getEnclosingFunctionIR()
}
override string getProperty(string key) {

View File

@@ -6,7 +6,7 @@ language[monotonicAggregates]
int getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
result = getBinaryInstructionValue(instr) or
result = neg(getConstantValue(instr.(NegateInstruction).getOperand())) or
result = neg(getConstantValue(instr.(NegateInstruction).getUnary())) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
@@ -25,8 +25,8 @@ int getConstantValueToPhi(Instruction def) {
pragma[noinline]
private predicate binaryInstructionOperands(BinaryInstruction instr, int left, int right) {
left = getConstantValue(instr.getLeftOperand()) and
right = getConstantValue(instr.getRightOperand())
left = getConstantValue(instr.getLeft()) and
right = getConstantValue(instr.getRight())
}
pragma[noinline]

View File

@@ -136,71 +136,71 @@ private predicate numberableInstruction(Instruction instr) {
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
FunctionIR funcIR, IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR
instr.getEnclosingFunctionIR() = funcIR
}
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
string value) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getResultType() = type and
instr.getValue() = value
}
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
Field field, ValueNumber objectAddress) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getField() = field and
valueNumber(instr.getObjectAddress()) = objectAddress
}
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof PointerArithmeticInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getResultType() = type and
instr.getElementSize() = elementSize and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
/**
@@ -208,7 +208,7 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
* to determine if two instances of that instruction are equivalent.
*/
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr.getResultType() instanceof VoidType) and
not numberableInstruction(instr)
}
@@ -237,7 +237,7 @@ ValueNumber valueNumberOfOperand(Operand op) {
*/
private ValueNumber nonUniqueValueNumber(Instruction instr) {
exists(FunctionIR funcIR |
funcIR = instr.getFunctionIR() and
funcIR = instr.getEnclosingFunctionIR() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, funcIR, var) and

View File

@@ -51,7 +51,7 @@ predicate operandIsConsumedWithoutEscaping(Operand operand) {
// loaded/stored value could).
operand instanceof AddressOperand or
exists (Instruction instr |
instr = operand.getInstruction() and
instr = operand.getUseInstruction() and
(
// Neither operand of a Compare escapes.
instr instanceof CompareInstruction or
@@ -82,7 +82,7 @@ IntValue getConstantValue(Instruction instr) {
IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
exists(IntValue bitOffset |
(
bitOffset = Ints::mul(Ints::mul(getConstantValue(instr.getRightOperand()),
bitOffset = Ints::mul(Ints::mul(getConstantValue(instr.getRight()),
instr.getElementSize()), 8)
) and
(
@@ -100,7 +100,7 @@ IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
*/
predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
exists(Instruction instr |
instr = operand.getInstruction() and
instr = operand.getUseInstruction() and
(
// Converting to a non-virtual base class adds the offset of the base class.
exists(ConvertToBaseInstruction convert |
@@ -151,7 +151,7 @@ predicate operandEscapes(Operand operand) {
operandIsConsumedWithoutEscaping(operand) or
// The address is propagated to the result of the instruction, but that
// result does not itself escape.
operandIsPropagated(operand, _) and not resultEscapes(operand.getInstruction())
operandIsPropagated(operand, _) and not resultEscapes(operand.getUseInstruction())
)
}
@@ -170,11 +170,11 @@ predicate resultEscapes(Instruction instr) {
*/
private predicate automaticVariableAddressEscapes(IRAutomaticVariable var) {
exists(FunctionIR funcIR |
funcIR = var.getFunctionIR() and
funcIR = var.getEnclosingFunctionIR() and
// The variable's address escapes if the result of any
// VariableAddressInstruction that computes the variable's address escapes.
exists(VariableAddressInstruction instr |
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var and
resultEscapes(instr)
)

View File

@@ -20,7 +20,7 @@ private VirtualIRVariable getVirtualVariable(IRVariable var) {
}
private UnknownVirtualVariable getUnknownVirtualVariable(FunctionIR f) {
result.getFunctionIR() = f
result.getEnclosingFunctionIR() = f
}
class VirtualVariable extends TVirtualVariable {
@@ -81,7 +81,7 @@ class UnknownVirtualVariable extends VirtualVariable, TUnknownVirtualVariable {
result instanceof UnknownType
}
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result = f
}
}
@@ -135,7 +135,7 @@ class VariableMemoryAccess extends TVariableMemoryAccess, MemoryAccess {
final override VirtualVariable getVirtualVariable() {
result = getVirtualVariable(var) or
not exists(getVirtualVariable(var)) and result = getUnknownVirtualVariable(var.getFunctionIR())
not exists(getVirtualVariable(var)) and result = getUnknownVirtualVariable(var.getEnclosingFunctionIR())
}
IntValue getOffset() {
@@ -254,11 +254,11 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
result = getVariableMemoryAccess(var, i, instr.getResultSize())
)
else (
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getFunctionIR())) and
result = TUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingFunctionIR())) and
not instr instanceof UnmodeledDefinitionInstruction and
not instr instanceof AliasedDefinitionInstruction
or
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(instr.getFunctionIR())) and
result = TTotalUnknownMemoryAccess(TUnknownVirtualVariable(instr.getEnclosingFunctionIR())) and
instr instanceof AliasedDefinitionInstruction
)
}
@@ -274,7 +274,7 @@ MemoryAccess getOperandMemoryAccess(Operand operand) {
size = operand.getDefinitionInstruction().getResultSize()
)
else (
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getInstruction().getFunctionIR())) and
not operand.getInstruction() instanceof UnmodeledUseInstruction
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getUseInstruction().getEnclosingFunctionIR())) and
not operand.getUseInstruction() instanceof UnmodeledUseInstruction
)
}

View File

@@ -57,7 +57,7 @@ cached private module Cached {
} or
Unreached(Function function) {
exists(OldInstruction oldInstruction |
function = oldInstruction.getFunction() and
function = oldInstruction.getEnclosingFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
)
}
@@ -65,7 +65,7 @@ cached private module Cached {
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
Type type) {
exists(OldIR::IRTempVariable var |
var.getFunction() = func and
var.getEnclosingFunction() = func and
var.getAST() = ast and
var.getTag() = tag and
var.getType() = type
@@ -99,7 +99,7 @@ cached private module Cached {
)
)
else (
result = instruction.getFunctionIR().getUnmodeledDefinitionInstruction()
result = instruction.getEnclosingFunctionIR().getUnmodeledDefinitionInstruction()
)
) or
// Connect any definitions that are not being modeled in SSA to the
@@ -190,7 +190,7 @@ cached private module Cached {
oldInstruction = getOldInstruction(instruction) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
result = Unreached(instruction.getFunction())
result = Unreached(instruction.getEnclosingFunction())
)
else (
result = getNewInstruction(oldInstruction.getSuccessor(kind))
@@ -287,12 +287,12 @@ cached private module Cached {
or
instruction = Chi(oldInstruction)
|
result.getFunction() = oldInstruction.getFunction()
result.getFunction() = oldInstruction.getEnclosingFunction()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result.getFunction() = block.getFunction()
result.getFunction() = block.getEnclosingFunction()
)
or
instruction = Unreached(result.getFunction())
@@ -553,7 +553,7 @@ cached private module CachedForDebugging {
}
private OldIR::IRTempVariable getOldTempVariable(IRTempVariable var) {
result.getFunction() = var.getFunction() and
result.getEnclosingFunction() = var.getEnclosingFunction() and
result.getAST() = var.getAST() and
result.getTag() = var.getTag()
}

View File

@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
* Gets all instructions in this function.
*/
final Instruction getAnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
* Gets all blocks in this function.
*/
final IRBlock getABlock() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
}

View File

@@ -33,7 +33,7 @@ class IRBlockBase extends TIRBlock {
*/
int getDisplayIndex() {
this = rank[result + 1](IRBlock funcBlock |
funcBlock.getFunction() = getFunction() |
funcBlock.getEnclosingFunction() = getEnclosingFunction() |
funcBlock order by funcBlock.getUniqueId()
)
}
@@ -63,12 +63,12 @@ class IRBlockBase extends TIRBlock {
result = strictcount(getInstruction(_))
}
final FunctionIR getFunctionIR() {
result = getFirstInstruction(this).getFunctionIR()
final FunctionIR getEnclosingFunctionIR() {
result = getFirstInstruction(this).getEnclosingFunctionIR()
}
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
final Function getEnclosingFunction() {
result = getFirstInstruction(this).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 = getFunctionIR().getEntryBlock() or
this = getEnclosingFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -7,7 +7,7 @@ private import semmle.code.cpp.ir.internal.TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
result.getVariable() = var and
result.getFunction() = func
result.getEnclosingFunction() = func
}
/**
@@ -47,14 +47,14 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the IR for the function that references this variable.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result.getFunction() = func
}
/**
* Gets the function that references this variable.
*/
final Function getFunction() {
final Function getEnclosingFunction() {
result = func
}
}

View File

@@ -123,7 +123,7 @@ module InstructionSanity {
query predicate unexplainedLoop(Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getFunction() = f and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
@@ -143,9 +143,9 @@ module InstructionSanity {
* a different function.
*/
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
operand.getInstruction() = instr and
operand.getUseInstruction() = instr and
operand.getDefinitionInstruction() = defInstr and
instr.getFunctionIR() != defInstr.getFunctionIR()
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
}
/**
@@ -169,7 +169,7 @@ module InstructionSanity {
query predicate containsLoopOfForwardEdges(FunctionIR f) {
exists(IRBlock block |
forwardEdge+(block, block) and
block.getFunctionIR() = f
block.getEnclosingFunctionIR() = f
)
}
@@ -196,10 +196,10 @@ module InstructionSanity {
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
fromBlock = count(IRBlock b1, IRBlock b2 |
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
b1.getEnclosingFunction() = f and b1.getBackEdgeSuccessor(_) = b2
) and
fromInstr != fromBlock
}
@@ -364,14 +364,14 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getFunction() {
result = getFunctionIR().getFunction()
final Function getEnclosingFunction() {
result = getEnclosingFunctionIR().getFunction()
}
/**
* Gets the FunctionIR object that contains the IR for this instruction.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result = Construction::getInstructionEnclosingFunctionIR(this)
}
@@ -472,7 +472,7 @@ class Instruction extends Construction::TInstruction {
* Gets all of this instruction's operands.
*/
final Operand getAnOperand() {
result.getInstruction() = this
result.getUseInstruction() = this
}
/**
@@ -665,8 +665,12 @@ class FieldAddressInstruction extends FieldInstruction {
getOpcode() instanceof Opcode::FieldAddress
}
final UnaryOperand getObjectAddressOperand() {
result = getAnOperand()
}
final Instruction getObjectAddress() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
result = getObjectAddressOperand().getDefinitionInstruction()
}
}
@@ -710,8 +714,12 @@ class ReturnValueInstruction extends ReturnInstruction {
getOpcode() instanceof Opcode::ReturnValue
}
final ReturnValueOperand getReturnValueOperand() {
result = getAnOperand()
}
final Instruction getReturnValue() {
result = getAnOperand().(ReturnValueOperand).getDefinitionInstruction()
result = getReturnValueOperand().getDefinitionInstruction()
}
}
@@ -720,8 +728,12 @@ class CopyInstruction extends Instruction {
getOpcode() instanceof CopyOpcode
}
final CopySourceOperand getSourceValueOperand() {
result = getAnOperand()
}
final Instruction getSourceValue() {
result = getAnOperand().(CopySourceOperand).getDefinitionInstruction()
result = getSourceValueOperand().getDefinitionInstruction()
}
}
@@ -736,8 +748,12 @@ class LoadInstruction extends CopyInstruction {
getOpcode() instanceof Opcode::Load
}
final AddressOperand getSourceAddressOperand() {
result = getAnOperand()
}
final Instruction getSourceAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getSourceAddressOperand().getDefinitionInstruction()
}
}
@@ -750,8 +766,12 @@ class StoreInstruction extends CopyInstruction {
result instanceof IndirectMemoryAccess
}
final AddressOperand getDestinationAddressOperand() {
result = getAnOperand()
}
final Instruction getDestinationAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getDestinationAddressOperand().getDefinitionInstruction()
}
}
@@ -760,8 +780,12 @@ class ConditionalBranchInstruction extends Instruction {
getOpcode() instanceof Opcode::ConditionalBranch
}
final ConditionOperand getConditionOperand() {
result = getAnOperand()
}
final Instruction getCondition() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getConditionOperand().getDefinitionInstruction()
}
final Instruction getTrueSuccessor() {
@@ -818,21 +842,29 @@ class BinaryInstruction extends Instruction {
getOpcode() instanceof BinaryOpcode
}
final Instruction getLeftOperand() {
result = getAnOperand().(LeftOperand).getDefinitionInstruction()
final LeftOperand getLeftOperand() {
result = getAnOperand()
}
final RightOperand getRightOperand() {
result = getAnOperand()
}
final Instruction getRightOperand() {
result = getAnOperand().(RightOperand).getDefinitionInstruction()
final Instruction getLeft() {
result = getLeftOperand().getDefinitionInstruction()
}
final Instruction getRight() {
result = getRightOperand().getDefinitionInstruction()
}
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
op1 = getAnOperand().(LeftOperand) and op2 = getAnOperand().(RightOperand)
op1 = getLeftOperand() and op2 = getRightOperand()
or
op1 = getAnOperand().(RightOperand) and op2 = getAnOperand().(LeftOperand)
op1 = getRightOperand() and op2 = getLeftOperand()
}
}
@@ -948,8 +980,12 @@ class UnaryInstruction extends Instruction {
getOpcode() instanceof UnaryOpcode
}
final Instruction getOperand() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
final UnaryOperand getUnaryOperand() {
result = getAnOperand()
}
final Instruction getUnary() {
result = getUnaryOperand().getDefinitionInstruction()
}
}
@@ -1075,7 +1111,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Instruction getGreaterOperand() {
Instruction getGreater() {
none()
}
@@ -1085,7 +1121,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Instruction getLesserOperand() {
Instruction getLesser() {
none()
}
@@ -1102,12 +1138,12 @@ class CompareLTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLT
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1120,12 +1156,12 @@ class CompareGTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGT
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1138,12 +1174,12 @@ class CompareLEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLE
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1156,12 +1192,12 @@ class CompareGEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGE
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1174,8 +1210,12 @@ class SwitchInstruction extends Instruction {
getOpcode() instanceof Opcode::Switch
}
final ConditionOperand getExpressionOperand() {
result = getAnOperand()
}
final Instruction getExpression() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getExpressionOperand().getDefinitionInstruction()
}
final Instruction getACaseSuccessor() {
@@ -1197,38 +1237,63 @@ class CallInstruction extends Instruction {
getOpcode() instanceof Opcode::Call
}
/**
* Gets the operand the specifies the target function of the call.
*/
final CallTargetOperand getCallTargetOperand() {
result = getAnOperand()
}
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
final Instruction getCallTarget() {
result = getAnOperand().(CallTargetOperand).getDefinitionInstruction()
result = getCallTargetOperand().getDefinitionInstruction()
}
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
final ArgumentOperand getAnArgumentOperand() {
result = getAnOperand()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
final Instruction getAnArgument() {
result = getAnOperand().(ArgumentOperand).getDefinitionInstruction()
result = getAnArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
final ThisArgumentOperand getThisArgumentOperand() {
result = getAnOperand()
}
/**
* Gets the `this` pointer argument of the call, if any.
*/
final Instruction getThisArgument() {
result = getAnOperand().(ThisArgumentOperand).getDefinitionInstruction()
result = getThisArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the argument operand at the specified index.
*/
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
result = getAnOperand() and
result.getIndex() = index
}
/**
* Gets the argument at the specified index.
*/
final Instruction getPositionalArgument(int index) {
exists(PositionalArgumentOperand operand |
operand = getAnOperand() and
operand.getIndex() = index and
result = operand.getDefinitionInstruction()
)
result = getPositionalArgumentOperand(index).getDefinitionInstruction()
}
}
@@ -1337,6 +1402,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
BufferMayWriteSideEffectInstruction() {
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof BufferMayMemoryAccess
}
@@ -1359,18 +1425,32 @@ class ThrowValueInstruction extends ThrowInstruction {
getOpcode() instanceof Opcode::ThrowValue
}
/**
* Gets the address operand of the exception thrown by this instruction.
*/
final AddressOperand getExceptionAddressOperand() {
result = getAnOperand()
}
/**
* Gets the address of the exception thrown by this instruction.
*/
final Instruction getExceptionAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getExceptionAddressOperand().getDefinitionInstruction()
}
/**
* Gets the operand for the exception thrown by this instruction.
*/
final ExceptionOperand getExceptionOperand() {
result = getAnOperand()
}
/**
* Gets the exception thrown by this instruction.
*/
final Instruction getException() {
result = getAnOperand().(ExceptionOperand).getDefinitionInstruction()
result = getExceptionOperand().getDefinitionInstruction()
}
}
@@ -1552,15 +1632,30 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotalOperand() {
result = getAnOperand().(ChiTotalOperand).getDefinitionInstruction()
final ChiTotalOperand getTotalOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotal() {
result = getTotalOperand().getDefinitionInstruction()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartialOperand() {
result = getAnOperand().(ChiPartialOperand).getDefinitionInstruction()
final ChiPartialOperand getPartialOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() {
result = getPartialOperand().getDefinitionInstruction()
}
}

View File

@@ -6,11 +6,11 @@ import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import semmle.code.cpp.ir.internal.OperandTag
private newtype TOperand =
TNonPhiOperand(Instruction instr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(instr, tag)
TNonPhiOperand(Instruction useInstr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(useInstr, tag)
} or
TPhiOperand(PhiInstruction instr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(instr, predecessorBlock)
TPhiOperand(PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(useInstr, predecessorBlock)
}
/**
@@ -22,13 +22,13 @@ class Operand extends TOperand {
}
Location getLocation() {
result = getInstruction().getLocation()
result = getUseInstruction().getLocation()
}
/**
* Gets the `Instruction` that consumes this operand.
*/
Instruction getInstruction() {
Instruction getUseInstruction() {
none()
}
@@ -78,7 +78,7 @@ class Operand extends TOperand {
*/
final AddressOperand getAddressOperand() {
getMemoryAccess() instanceof IndirectMemoryAccess and
result.getInstruction() = getInstruction()
result.getUseInstruction() = getUseInstruction()
}
}
@@ -94,7 +94,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
this = TNonPhiOperand(instr, tag, defInstr)
}
override final Instruction getInstruction() {
override final Instruction getUseInstruction() {
result = instr
}
@@ -353,20 +353,20 @@ class SideEffectOperand extends NonPhiOperand {
* An operand of a `PhiInstruction`.
*/
class PhiOperand extends Operand, TPhiOperand {
PhiInstruction instr;
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
PhiOperand() {
this = TPhiOperand(instr, defInstr, predecessorBlock)
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
}
override string toString() {
result = "Phi"
}
override final PhiInstruction getInstruction() {
result = instr
override final PhiInstruction getUseInstruction() {
result = useInstr
}
override final Instruction getDefinitionInstruction() {

View File

@@ -53,10 +53,10 @@ private newtype TPrintableIRNode =
shouldPrintFunction(funcIR.getFunction())
} or
TPrintableIRBlock(IRBlock block) {
shouldPrintFunction(block.getFunction())
shouldPrintFunction(block.getEnclosingFunction())
} or
TPrintableInstruction(Instruction instr) {
shouldPrintFunction(instr.getFunction())
shouldPrintFunction(instr.getEnclosingFunction())
}
/**
@@ -185,7 +185,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
}
override final PrintableFunctionIR getParent() {
result.getFunctionIR() = block.getFunctionIR()
result.getFunctionIR() = block.getEnclosingFunctionIR()
}
override string getProperty(string key) {

View File

@@ -6,7 +6,7 @@ language[monotonicAggregates]
int getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
result = getBinaryInstructionValue(instr) or
result = neg(getConstantValue(instr.(NegateInstruction).getOperand())) or
result = neg(getConstantValue(instr.(NegateInstruction).getUnary())) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
@@ -25,8 +25,8 @@ int getConstantValueToPhi(Instruction def) {
pragma[noinline]
private predicate binaryInstructionOperands(BinaryInstruction instr, int left, int right) {
left = getConstantValue(instr.getLeftOperand()) and
right = getConstantValue(instr.getRightOperand())
left = getConstantValue(instr.getLeft()) and
right = getConstantValue(instr.getRight())
}
pragma[noinline]

View File

@@ -136,71 +136,71 @@ private predicate numberableInstruction(Instruction instr) {
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
FunctionIR funcIR, IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR
instr.getEnclosingFunctionIR() = funcIR
}
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
string value) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getResultType() = type and
instr.getValue() = value
}
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
Field field, ValueNumber objectAddress) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getField() = field and
valueNumber(instr.getObjectAddress()) = objectAddress
}
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof PointerArithmeticInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getResultType() = type and
instr.getElementSize() = elementSize and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
/**
@@ -208,7 +208,7 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
* to determine if two instances of that instruction are equivalent.
*/
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr.getResultType() instanceof VoidType) and
not numberableInstruction(instr)
}
@@ -237,7 +237,7 @@ ValueNumber valueNumberOfOperand(Operand op) {
*/
private ValueNumber nonUniqueValueNumber(Instruction instr) {
exists(FunctionIR funcIR |
funcIR = instr.getFunctionIR() and
funcIR = instr.getEnclosingFunctionIR() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, funcIR, var) and

View File

@@ -224,7 +224,7 @@ class TranslatedFunction extends TranslatedElement,
(
tag = UnmodeledUseTag() and
operandTag instanceof UnmodeledUseOperandTag and
result.getFunction() = func and
result.getEnclosingFunction() = func and
result.hasMemoryResult()
) or
(

View File

@@ -40,7 +40,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -48,17 +48,17 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
pragma[noinline]
final UnmodeledUseInstruction getUnmodeledUseInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -66,7 +66,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -75,7 +75,7 @@ class FunctionIR extends TFunctionIR {
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
@@ -90,13 +90,13 @@ class FunctionIR extends TFunctionIR {
* Gets all instructions in this function.
*/
final Instruction getAnInstruction() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
/**
* Gets all blocks in this function.
*/
final IRBlock getABlock() {
result.getFunctionIR() = this
result.getEnclosingFunctionIR() = this
}
}

View File

@@ -33,7 +33,7 @@ class IRBlockBase extends TIRBlock {
*/
int getDisplayIndex() {
this = rank[result + 1](IRBlock funcBlock |
funcBlock.getFunction() = getFunction() |
funcBlock.getEnclosingFunction() = getEnclosingFunction() |
funcBlock order by funcBlock.getUniqueId()
)
}
@@ -63,12 +63,12 @@ class IRBlockBase extends TIRBlock {
result = strictcount(getInstruction(_))
}
final FunctionIR getFunctionIR() {
result = getFirstInstruction(this).getFunctionIR()
final FunctionIR getEnclosingFunctionIR() {
result = getFirstInstruction(this).getEnclosingFunctionIR()
}
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
final Function getEnclosingFunction() {
result = getFirstInstruction(this).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 = getFunctionIR().getEntryBlock() or
this = getEnclosingFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -7,7 +7,7 @@ private import semmle.code.cpp.ir.internal.TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
result.getVariable() = var and
result.getFunction() = func
result.getEnclosingFunction() = func
}
/**
@@ -47,14 +47,14 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the IR for the function that references this variable.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result.getFunction() = func
}
/**
* Gets the function that references this variable.
*/
final Function getFunction() {
final Function getEnclosingFunction() {
result = func
}
}

View File

@@ -123,7 +123,7 @@ module InstructionSanity {
query predicate unexplainedLoop(Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getFunction() = f and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
@@ -143,9 +143,9 @@ module InstructionSanity {
* a different function.
*/
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
operand.getInstruction() = instr and
operand.getUseInstruction() = instr and
operand.getDefinitionInstruction() = defInstr and
instr.getFunctionIR() != defInstr.getFunctionIR()
instr.getEnclosingFunctionIR() != defInstr.getEnclosingFunctionIR()
}
/**
@@ -169,7 +169,7 @@ module InstructionSanity {
query predicate containsLoopOfForwardEdges(FunctionIR f) {
exists(IRBlock block |
forwardEdge+(block, block) and
block.getFunctionIR() = f
block.getEnclosingFunctionIR() = f
)
}
@@ -196,10 +196,10 @@ module InstructionSanity {
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
fromBlock = count(IRBlock b1, IRBlock b2 |
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
b1.getEnclosingFunction() = f and b1.getBackEdgeSuccessor(_) = b2
) and
fromInstr != fromBlock
}
@@ -364,14 +364,14 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getFunction() {
result = getFunctionIR().getFunction()
final Function getEnclosingFunction() {
result = getEnclosingFunctionIR().getFunction()
}
/**
* Gets the FunctionIR object that contains the IR for this instruction.
*/
final FunctionIR getFunctionIR() {
final FunctionIR getEnclosingFunctionIR() {
result = Construction::getInstructionEnclosingFunctionIR(this)
}
@@ -472,7 +472,7 @@ class Instruction extends Construction::TInstruction {
* Gets all of this instruction's operands.
*/
final Operand getAnOperand() {
result.getInstruction() = this
result.getUseInstruction() = this
}
/**
@@ -665,8 +665,12 @@ class FieldAddressInstruction extends FieldInstruction {
getOpcode() instanceof Opcode::FieldAddress
}
final UnaryOperand getObjectAddressOperand() {
result = getAnOperand()
}
final Instruction getObjectAddress() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
result = getObjectAddressOperand().getDefinitionInstruction()
}
}
@@ -710,8 +714,12 @@ class ReturnValueInstruction extends ReturnInstruction {
getOpcode() instanceof Opcode::ReturnValue
}
final ReturnValueOperand getReturnValueOperand() {
result = getAnOperand()
}
final Instruction getReturnValue() {
result = getAnOperand().(ReturnValueOperand).getDefinitionInstruction()
result = getReturnValueOperand().getDefinitionInstruction()
}
}
@@ -720,8 +728,12 @@ class CopyInstruction extends Instruction {
getOpcode() instanceof CopyOpcode
}
final CopySourceOperand getSourceValueOperand() {
result = getAnOperand()
}
final Instruction getSourceValue() {
result = getAnOperand().(CopySourceOperand).getDefinitionInstruction()
result = getSourceValueOperand().getDefinitionInstruction()
}
}
@@ -736,8 +748,12 @@ class LoadInstruction extends CopyInstruction {
getOpcode() instanceof Opcode::Load
}
final AddressOperand getSourceAddressOperand() {
result = getAnOperand()
}
final Instruction getSourceAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getSourceAddressOperand().getDefinitionInstruction()
}
}
@@ -750,8 +766,12 @@ class StoreInstruction extends CopyInstruction {
result instanceof IndirectMemoryAccess
}
final AddressOperand getDestinationAddressOperand() {
result = getAnOperand()
}
final Instruction getDestinationAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getDestinationAddressOperand().getDefinitionInstruction()
}
}
@@ -760,8 +780,12 @@ class ConditionalBranchInstruction extends Instruction {
getOpcode() instanceof Opcode::ConditionalBranch
}
final ConditionOperand getConditionOperand() {
result = getAnOperand()
}
final Instruction getCondition() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getConditionOperand().getDefinitionInstruction()
}
final Instruction getTrueSuccessor() {
@@ -818,21 +842,29 @@ class BinaryInstruction extends Instruction {
getOpcode() instanceof BinaryOpcode
}
final Instruction getLeftOperand() {
result = getAnOperand().(LeftOperand).getDefinitionInstruction()
final LeftOperand getLeftOperand() {
result = getAnOperand()
}
final RightOperand getRightOperand() {
result = getAnOperand()
}
final Instruction getRightOperand() {
result = getAnOperand().(RightOperand).getDefinitionInstruction()
final Instruction getLeft() {
result = getLeftOperand().getDefinitionInstruction()
}
final Instruction getRight() {
result = getRightOperand().getDefinitionInstruction()
}
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
op1 = getAnOperand().(LeftOperand) and op2 = getAnOperand().(RightOperand)
op1 = getLeftOperand() and op2 = getRightOperand()
or
op1 = getAnOperand().(RightOperand) and op2 = getAnOperand().(LeftOperand)
op1 = getRightOperand() and op2 = getLeftOperand()
}
}
@@ -948,8 +980,12 @@ class UnaryInstruction extends Instruction {
getOpcode() instanceof UnaryOpcode
}
final Instruction getOperand() {
result = getAnOperand().(UnaryOperand).getDefinitionInstruction()
final UnaryOperand getUnaryOperand() {
result = getAnOperand()
}
final Instruction getUnary() {
result = getUnaryOperand().getDefinitionInstruction()
}
}
@@ -1075,7 +1111,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Instruction getGreaterOperand() {
Instruction getGreater() {
none()
}
@@ -1085,7 +1121,7 @@ class RelationalInstruction extends CompareInstruction {
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Instruction getLesserOperand() {
Instruction getLesser() {
none()
}
@@ -1102,12 +1138,12 @@ class CompareLTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLT
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1120,12 +1156,12 @@ class CompareGTInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGT
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1138,12 +1174,12 @@ class CompareLEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareLE
}
override Instruction getLesserOperand() {
result = getLeftOperand()
override Instruction getLesser() {
result = getLeft()
}
override Instruction getGreaterOperand() {
result = getRightOperand()
override Instruction getGreater() {
result = getRight()
}
override predicate isStrict() {
@@ -1156,12 +1192,12 @@ class CompareGEInstruction extends RelationalInstruction {
getOpcode() instanceof Opcode::CompareGE
}
override Instruction getLesserOperand() {
result = getRightOperand()
override Instruction getLesser() {
result = getRight()
}
override Instruction getGreaterOperand() {
result = getLeftOperand()
override Instruction getGreater() {
result = getLeft()
}
override predicate isStrict() {
@@ -1174,8 +1210,12 @@ class SwitchInstruction extends Instruction {
getOpcode() instanceof Opcode::Switch
}
final ConditionOperand getExpressionOperand() {
result = getAnOperand()
}
final Instruction getExpression() {
result = getAnOperand().(ConditionOperand).getDefinitionInstruction()
result = getExpressionOperand().getDefinitionInstruction()
}
final Instruction getACaseSuccessor() {
@@ -1197,38 +1237,63 @@ class CallInstruction extends Instruction {
getOpcode() instanceof Opcode::Call
}
/**
* Gets the operand the specifies the target function of the call.
*/
final CallTargetOperand getCallTargetOperand() {
result = getAnOperand()
}
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
final Instruction getCallTarget() {
result = getAnOperand().(CallTargetOperand).getDefinitionInstruction()
result = getCallTargetOperand().getDefinitionInstruction()
}
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
final ArgumentOperand getAnArgumentOperand() {
result = getAnOperand()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
final Instruction getAnArgument() {
result = getAnOperand().(ArgumentOperand).getDefinitionInstruction()
result = getAnArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
final ThisArgumentOperand getThisArgumentOperand() {
result = getAnOperand()
}
/**
* Gets the `this` pointer argument of the call, if any.
*/
final Instruction getThisArgument() {
result = getAnOperand().(ThisArgumentOperand).getDefinitionInstruction()
result = getThisArgumentOperand().getDefinitionInstruction()
}
/**
* Gets the argument operand at the specified index.
*/
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
result = getAnOperand() and
result.getIndex() = index
}
/**
* Gets the argument at the specified index.
*/
final Instruction getPositionalArgument(int index) {
exists(PositionalArgumentOperand operand |
operand = getAnOperand() and
operand.getIndex() = index and
result = operand.getDefinitionInstruction()
)
result = getPositionalArgumentOperand(index).getDefinitionInstruction()
}
}
@@ -1337,6 +1402,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
BufferMayWriteSideEffectInstruction() {
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof BufferMayMemoryAccess
}
@@ -1359,18 +1425,32 @@ class ThrowValueInstruction extends ThrowInstruction {
getOpcode() instanceof Opcode::ThrowValue
}
/**
* Gets the address operand of the exception thrown by this instruction.
*/
final AddressOperand getExceptionAddressOperand() {
result = getAnOperand()
}
/**
* Gets the address of the exception thrown by this instruction.
*/
final Instruction getExceptionAddress() {
result = getAnOperand().(AddressOperand).getDefinitionInstruction()
result = getExceptionAddressOperand().getDefinitionInstruction()
}
/**
* Gets the operand for the exception thrown by this instruction.
*/
final ExceptionOperand getExceptionOperand() {
result = getAnOperand()
}
/**
* Gets the exception thrown by this instruction.
*/
final Instruction getException() {
result = getAnOperand().(ExceptionOperand).getDefinitionInstruction()
result = getExceptionOperand().getDefinitionInstruction()
}
}
@@ -1552,15 +1632,30 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotalOperand() {
result = getAnOperand().(ChiTotalOperand).getDefinitionInstruction()
final ChiTotalOperand getTotalOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
final Instruction getTotal() {
result = getTotalOperand().getDefinitionInstruction()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartialOperand() {
result = getAnOperand().(ChiPartialOperand).getDefinitionInstruction()
final ChiPartialOperand getPartialOperand() {
result = getAnOperand()
}
/**
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() {
result = getPartialOperand().getDefinitionInstruction()
}
}

View File

@@ -6,11 +6,11 @@ import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import semmle.code.cpp.ir.internal.OperandTag
private newtype TOperand =
TNonPhiOperand(Instruction instr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(instr, tag)
TNonPhiOperand(Instruction useInstr, OperandTag tag, Instruction defInstr) {
defInstr = Construction::getInstructionOperandDefinition(useInstr, tag)
} or
TPhiOperand(PhiInstruction instr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(instr, predecessorBlock)
TPhiOperand(PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock) {
defInstr = Construction::getPhiInstructionOperandDefinition(useInstr, predecessorBlock)
}
/**
@@ -22,13 +22,13 @@ class Operand extends TOperand {
}
Location getLocation() {
result = getInstruction().getLocation()
result = getUseInstruction().getLocation()
}
/**
* Gets the `Instruction` that consumes this operand.
*/
Instruction getInstruction() {
Instruction getUseInstruction() {
none()
}
@@ -78,7 +78,7 @@ class Operand extends TOperand {
*/
final AddressOperand getAddressOperand() {
getMemoryAccess() instanceof IndirectMemoryAccess and
result.getInstruction() = getInstruction()
result.getUseInstruction() = getUseInstruction()
}
}
@@ -94,7 +94,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
this = TNonPhiOperand(instr, tag, defInstr)
}
override final Instruction getInstruction() {
override final Instruction getUseInstruction() {
result = instr
}
@@ -353,20 +353,20 @@ class SideEffectOperand extends NonPhiOperand {
* An operand of a `PhiInstruction`.
*/
class PhiOperand extends Operand, TPhiOperand {
PhiInstruction instr;
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
PhiOperand() {
this = TPhiOperand(instr, defInstr, predecessorBlock)
this = TPhiOperand(useInstr, defInstr, predecessorBlock)
}
override string toString() {
result = "Phi"
}
override final PhiInstruction getInstruction() {
result = instr
override final PhiInstruction getUseInstruction() {
result = useInstr
}
override final Instruction getDefinitionInstruction() {

View File

@@ -53,10 +53,10 @@ private newtype TPrintableIRNode =
shouldPrintFunction(funcIR.getFunction())
} or
TPrintableIRBlock(IRBlock block) {
shouldPrintFunction(block.getFunction())
shouldPrintFunction(block.getEnclosingFunction())
} or
TPrintableInstruction(Instruction instr) {
shouldPrintFunction(instr.getFunction())
shouldPrintFunction(instr.getEnclosingFunction())
}
/**
@@ -185,7 +185,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
}
override final PrintableFunctionIR getParent() {
result.getFunctionIR() = block.getFunctionIR()
result.getFunctionIR() = block.getEnclosingFunctionIR()
}
override string getProperty(string key) {

View File

@@ -6,7 +6,7 @@ language[monotonicAggregates]
int getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
result = getBinaryInstructionValue(instr) or
result = neg(getConstantValue(instr.(NegateInstruction).getOperand())) or
result = neg(getConstantValue(instr.(NegateInstruction).getUnary())) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
@@ -25,8 +25,8 @@ int getConstantValueToPhi(Instruction def) {
pragma[noinline]
private predicate binaryInstructionOperands(BinaryInstruction instr, int left, int right) {
left = getConstantValue(instr.getLeftOperand()) and
right = getConstantValue(instr.getRightOperand())
left = getConstantValue(instr.getLeft()) and
right = getConstantValue(instr.getRight())
}
pragma[noinline]

View File

@@ -136,71 +136,71 @@ private predicate numberableInstruction(Instruction instr) {
private predicate variableAddressValueNumber(VariableAddressInstruction instr, FunctionIR funcIR,
IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeParameterValueNumber(InitializeParameterInstruction instr,
FunctionIR funcIR, IRVariable var) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR
instr.getEnclosingFunctionIR() = funcIR
}
private predicate constantValueNumber(ConstantInstruction instr, FunctionIR funcIR, Type type,
string value) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getResultType() = type and
instr.getValue() = value
}
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, FunctionIR funcIR,
Field field, ValueNumber objectAddress) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getField() = field and
valueNumber(instr.getObjectAddress()) = objectAddress
}
private predicate binaryValueNumber(BinaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber leftOperand, ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof PointerArithmeticInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate pointerArithmeticValueNumber(PointerArithmeticInstruction instr,
FunctionIR funcIR, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getResultType() = type and
instr.getElementSize() = elementSize and
valueNumber(instr.getLeftOperand()) = leftOperand and
valueNumber(instr.getRightOperand()) = rightOperand
valueNumber(instr.getLeft()) = leftOperand and
valueNumber(instr.getRight()) = rightOperand
}
private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Opcode opcode,
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
valueNumber(instr.getUnary()) = operand
}
/**
@@ -208,7 +208,7 @@ private predicate inheritanceConversionValueNumber(InheritanceConversionInstruct
* to determine if two instances of that instruction are equivalent.
*/
private predicate uniqueValueNumber(Instruction instr, FunctionIR funcIR) {
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
(not instr.getResultType() instanceof VoidType) and
not numberableInstruction(instr)
}
@@ -237,7 +237,7 @@ ValueNumber valueNumberOfOperand(Operand op) {
*/
private ValueNumber nonUniqueValueNumber(Instruction instr) {
exists(FunctionIR funcIR |
funcIR = instr.getFunctionIR() and
funcIR = instr.getEnclosingFunctionIR() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, funcIR, var) and

View File

@@ -51,7 +51,7 @@ predicate operandIsConsumedWithoutEscaping(Operand operand) {
// loaded/stored value could).
operand instanceof AddressOperand or
exists (Instruction instr |
instr = operand.getInstruction() and
instr = operand.getUseInstruction() and
(
// Neither operand of a Compare escapes.
instr instanceof CompareInstruction or
@@ -82,7 +82,7 @@ IntValue getConstantValue(Instruction instr) {
IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
exists(IntValue bitOffset |
(
bitOffset = Ints::mul(Ints::mul(getConstantValue(instr.getRightOperand()),
bitOffset = Ints::mul(Ints::mul(getConstantValue(instr.getRight()),
instr.getElementSize()), 8)
) and
(
@@ -100,7 +100,7 @@ IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
*/
predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
exists(Instruction instr |
instr = operand.getInstruction() and
instr = operand.getUseInstruction() and
(
// Converting to a non-virtual base class adds the offset of the base class.
exists(ConvertToBaseInstruction convert |
@@ -151,7 +151,7 @@ predicate operandEscapes(Operand operand) {
operandIsConsumedWithoutEscaping(operand) or
// The address is propagated to the result of the instruction, but that
// result does not itself escape.
operandIsPropagated(operand, _) and not resultEscapes(operand.getInstruction())
operandIsPropagated(operand, _) and not resultEscapes(operand.getUseInstruction())
)
}
@@ -170,11 +170,11 @@ predicate resultEscapes(Instruction instr) {
*/
private predicate automaticVariableAddressEscapes(IRAutomaticVariable var) {
exists(FunctionIR funcIR |
funcIR = var.getFunctionIR() and
funcIR = var.getEnclosingFunctionIR() and
// The variable's address escapes if the result of any
// VariableAddressInstruction that computes the variable's address escapes.
exists(VariableAddressInstruction instr |
instr.getFunctionIR() = funcIR and
instr.getEnclosingFunctionIR() = funcIR and
instr.getVariable() = var and
resultEscapes(instr)
)

View File

@@ -57,7 +57,7 @@ cached private module Cached {
} or
Unreached(Function function) {
exists(OldInstruction oldInstruction |
function = oldInstruction.getFunction() and
function = oldInstruction.getEnclosingFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
)
}
@@ -65,7 +65,7 @@ cached private module Cached {
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
Type type) {
exists(OldIR::IRTempVariable var |
var.getFunction() = func and
var.getEnclosingFunction() = func and
var.getAST() = ast and
var.getTag() = tag and
var.getType() = type
@@ -99,7 +99,7 @@ cached private module Cached {
)
)
else (
result = instruction.getFunctionIR().getUnmodeledDefinitionInstruction()
result = instruction.getEnclosingFunctionIR().getUnmodeledDefinitionInstruction()
)
) or
// Connect any definitions that are not being modeled in SSA to the
@@ -190,7 +190,7 @@ cached private module Cached {
oldInstruction = getOldInstruction(instruction) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
result = Unreached(instruction.getFunction())
result = Unreached(instruction.getEnclosingFunction())
)
else (
result = getNewInstruction(oldInstruction.getSuccessor(kind))
@@ -287,12 +287,12 @@ cached private module Cached {
or
instruction = Chi(oldInstruction)
|
result.getFunction() = oldInstruction.getFunction()
result.getFunction() = oldInstruction.getEnclosingFunction()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result.getFunction() = block.getFunction()
result.getFunction() = block.getEnclosingFunction()
)
or
instruction = Unreached(result.getFunction())
@@ -553,7 +553,7 @@ cached private module CachedForDebugging {
}
private OldIR::IRTempVariable getOldTempVariable(IRTempVariable var) {
result.getFunction() = var.getFunction() and
result.getEnclosingFunction() = var.getEnclosingFunction() and
result.getAST() = var.getAST() and
result.getTag() = var.getTag()
}

View File

@@ -144,7 +144,7 @@ private predicate boundFlowStepSsa(
) {
exists(IRGuardCondition guard, boolean testIsTrue |
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
guard.controls(op2.getInstruction().getBlock(), testIsTrue) and
guard.controls(op2.getUseInstruction().getBlock(), testIsTrue) and
reason = TCondReason(guard)
)
}
@@ -217,10 +217,10 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
private class SafeCastInstruction extends ConvertInstruction {
SafeCastInstruction() {
safeCast(getResultType(), getOperand().getResultType())
safeCast(getResultType(), getUnary().getResultType())
or
getResultType() instanceof PointerType and
getOperand().getResultType() instanceof PointerType
getUnary().getResultType() instanceof PointerType
}
}
@@ -269,8 +269,8 @@ private predicate boundFlowStep(Instruction i, NonPhiOperand op, int delta, bool
i.(AddInstruction).getAnOperand() = x and
op != x
|
not exists(getValue(getConstantValue(op.getInstruction()))) and
not exists(getValue(getConstantValue(x.getInstruction()))) and
not exists(getValue(getConstantValue(op.getUseInstruction()))) and
not exists(getValue(getConstantValue(x.getUseInstruction()))) and
if(strictlyPositive(x))
then (
upper = false and delta = 1
@@ -288,12 +288,12 @@ private predicate boundFlowStep(Instruction i, NonPhiOperand op, int delta, bool
exists(Operand x |
exists(SubInstruction sub |
i = sub and
sub.getAnOperand().(LeftOperand) = op and
sub.getAnOperand().(RightOperand) = x
sub.getLeftOperand() = op and
sub.getRightOperand() = x
)
|
// `x` with constant value is covered by valueFlowStep
not exists(getValue(getConstantValue(x.getInstruction()))) and
not exists(getValue(getConstantValue(x.getUseInstruction()))) and
if strictlyPositive(x)
then (
upper = true and delta = -1
@@ -308,9 +308,9 @@ private predicate boundFlowStep(Instruction i, NonPhiOperand op, int delta, bool
) else if negative(x) then (upper = false and delta = 0) else none()
)
or
i.(RemInstruction).getAnOperand().(RightOperand) = op and positive(op) and delta = -1 and upper = true
i.(RemInstruction).getRightOperand() = op and positive(op) and delta = -1 and upper = true
or
i.(RemInstruction).getAnOperand().(LeftOperand) = op and positive(op) and delta = 0 and upper = true
i.(RemInstruction).getLeftOperand() = op and positive(op) and delta = 0 and upper = true
or
i.(BitAndInstruction).getAnOperand() = op and positive(op) and delta = 0 and upper = true
or
@@ -323,7 +323,7 @@ private predicate boundFlowStepMul(Instruction i1, Operand op, int factor) {
i1.(MulInstruction).hasOperands(op, c.getAUse()) and factor = k
or
exists(ShiftLeftInstruction i |
i = i1 and i.getAnOperand().(LeftOperand) = op and i.getAnOperand().(RightOperand) = c.getAUse() and factor = 2.pow(k)
i = i1 and i.getLeftOperand() = op and i.getRightOperand() = c.getAUse() and factor = 2.pow(k)
)
)
}
@@ -331,11 +331,11 @@ private predicate boundFlowStepMul(Instruction i1, Operand op, int factor) {
private predicate boundFlowStepDiv(Instruction i1, Operand op, int factor) {
exists(Instruction c, int k | k = getValue(getConstantValue(c)) and k > 0 |
exists(DivInstruction i |
i = i1 and i.getAnOperand().(LeftOperand) = op and i.getRightOperand() = c and factor = k
i = i1 and i.getLeftOperand() = op and i.getRight() = c and factor = k
)
or
exists(ShiftRightInstruction i |
i = i1 and i.getAnOperand().(LeftOperand) = op and i.getRightOperand() = c and factor = 2.pow(k)
i = i1 and i.getLeftOperand() = op and i.getRight() = c and factor = 2.pow(k)
)
)
}
@@ -387,7 +387,7 @@ private predicate boundFlowStepPhi(
exists(IRGuardCondition guard, boolean testIsTrue |
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
(
guard.hasBranchEdge(op2.getPredecessorBlock().getLastInstruction(), op2.getInstruction().getBlock(), testIsTrue)
guard.hasBranchEdge(op2.getPredecessorBlock().getLastInstruction(), op2.getUseInstruction().getBlock(), testIsTrue)
or
guard.controls(op2.getPredecessorBlock(), testIsTrue)
) and
@@ -431,7 +431,7 @@ private predicate unequalFlowStep(
) {
exists(IRGuardCondition guard, boolean testIsTrue |
guard = eqFlowCond(valueNumberOfOperand(op2), op1, delta, false, testIsTrue) and
guard.controls(op2.getInstruction().getBlock(), testIsTrue) and
guard.controls(op2.getUseInstruction().getBlock(), testIsTrue) and
reason = TCondReason(guard)
)
}

View File

@@ -10,8 +10,8 @@ IntValue getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
exists(BinaryInstruction binInstr, IntValue left, IntValue right |
binInstr = instr and
left = getConstantValue(binInstr.getLeftOperand()) and
right = getConstantValue(binInstr.getRightOperand()) and
left = getConstantValue(binInstr.getLeft()) and
right = getConstantValue(binInstr.getRight()) and
(
binInstr instanceof AddInstruction and result = add(left, right) or
binInstr instanceof SubInstruction and result = sub(left, right) or
@@ -39,8 +39,8 @@ predicate valueFlowStep(Instruction i, Operand op, int delta) {
)
or
exists(Operand x |
i.(SubInstruction).getAnOperand().(LeftOperand) = op and
i.(SubInstruction).getAnOperand().(RightOperand) = x
i.(SubInstruction).getLeftOperand() = op and
i.(SubInstruction).getRightOperand() = x
|
delta = -getValue(getConstantValue(x.getDefinitionInstruction()))
)
@@ -55,8 +55,8 @@ predicate valueFlowStep(Instruction i, Operand op, int delta) {
)
or
exists(Operand x |
i.(PointerSubInstruction).getAnOperand().(LeftOperand) = op and
i.(PointerSubInstruction).getAnOperand().(RightOperand) = x
i.(PointerSubInstruction).getLeftOperand() = op and
i.(PointerSubInstruction).getRightOperand() = x
|
delta = i.(PointerSubInstruction).getElementSize() *
-getValue(getConstantValue(x.getDefinitionInstruction()))

View File

@@ -132,7 +132,7 @@ private newtype CastKind = TWiden() or TSame() or TNarrow()
private CastKind getCastKind(ConvertInstruction ci) {
exists(int fromSize, int toSize |
toSize = ci.getResultSize() and
fromSize = ci.getOperand().getResultSize()
fromSize = ci.getUnary().getResultSize()
|
fromSize < toSize and
result = TWiden()
@@ -229,7 +229,7 @@ private predicate lowerBound(IRGuardCondition comp, Operand lowerbound, Operand
isStrict = false and
adjustment = 1
) and
comp.ensuresLt(lowerbound, compared, adjustment, bounded.getInstruction().getBlock(), true)
comp.ensuresLt(lowerbound, compared, adjustment, bounded.getUseInstruction().getBlock(), true)
)
}
@@ -248,7 +248,7 @@ private predicate upperBound(IRGuardCondition comp, Operand upperbound, Operand
isStrict = false and
adjustment = 1
) and
comp.ensuresLt(compared, upperbound, adjustment, bounded.getInstruction().getBlock(), true)
comp.ensuresLt(compared, upperbound, adjustment, bounded.getUseInstruction().getBlock(), true)
)
}
@@ -262,7 +262,7 @@ private predicate upperBound(IRGuardCondition comp, Operand upperbound, Operand
private predicate eqBound(IRGuardCondition guard, Operand eqbound, Operand bounded, boolean isEq) {
exists(Operand compared |
valueNumber(bounded.getDefinitionInstruction()) = valueNumber(compared.getDefinitionInstruction()) and
guard.ensuresEq(compared, eqbound, 0, bounded.getInstruction().getBlock(), isEq)
guard.ensuresEq(compared, eqbound, 0, bounded.getUseInstruction().getBlock(), isEq)
)
}
@@ -316,16 +316,16 @@ private predicate zeroBoundOk(IRGuardCondition comp, Operand bound, Operand op)
eqBound(comp, bound, op, false) and TZero() != operandSign(bound)
}
private Sign binaryOpLhsSign(Instruction i) {
result = operandSign(i.getAnOperand().(LeftOperand))
private Sign binaryOpLhsSign(BinaryInstruction i) {
result = operandSign(i.getLeftOperand())
}
private Sign binaryOpRhsSign(Instruction i) {
result = operandSign(i.getAnOperand().(RightOperand))
private Sign binaryOpRhsSign(BinaryInstruction i) {
result = operandSign(i.getRightOperand())
}
pragma[noinline]
private predicate binaryOpSigns(Instruction i, Sign lhs, Sign rhs) {
private predicate binaryOpSigns(BinaryInstruction i, Sign lhs, Sign rhs) {
lhs = binaryOpLhsSign(i) and
rhs = binaryOpRhsSign(i)
}
@@ -384,7 +384,7 @@ cached module SignAnalysisCached {
or
exists(ConvertInstruction ci, Instruction prior, boolean fromSigned, boolean toSigned |
i = ci and
prior = ci.getOperand() and
prior = ci.getUnary() and
(
if ci.getResultType().(IntegralType).isSigned()
then toSigned = true

View File

@@ -13,7 +13,7 @@ predicate shouldEscape(IRAutomaticUserVariable var) {
from IRAutomaticUserVariable var
where
exists(FunctionIR funcIR |
funcIR = var.getFunctionIR() and
funcIR = var.getEnclosingFunctionIR() and
(
(shouldEscape(var) and variableAddressEscapes(var)) or
(not shouldEscape(var) and not variableAddressEscapes(var))

View File

@@ -12,7 +12,7 @@ predicate shouldEscape(IRAutomaticUserVariable var) {
from IRAutomaticUserVariable var
where
exists(FunctionIR funcIR |
funcIR = var.getFunctionIR() and
funcIR = var.getEnclosingFunctionIR() and
(
(shouldEscape(var) and variableAddressEscapes(var)) or
(not shouldEscape(var) and not variableAddressEscapes(var))