mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
C++: Add getUpdatedInterval predicate to ChiInstructions, and getUsedInterval predicate to NonPhiMemoryOperands.
This commit is contained in:
@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
|
||||
* Gets the operand that represents the new value written by the memory write.
|
||||
*/
|
||||
final Instruction getPartial() { result = getPartialOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
|
||||
*/
|
||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the operand totally overlaps with its definition and consumes the
|
||||
* bit range `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
|
||||
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -556,22 +556,6 @@ private Overlap getVariableMemoryLocationOverlap(
|
||||
use.getEndBitOffset())
|
||||
}
|
||||
|
||||
predicate getDefInterval(Instruction defInstr, IntValue startBitDef, IntValue endBitDef) {
|
||||
exists(VariableMemoryLocation def |
|
||||
def = getResultMemoryLocation(defInstr) and
|
||||
startBitDef = def.getStartBitOffset() and
|
||||
endBitDef = def.getEndBitOffset()
|
||||
)
|
||||
}
|
||||
|
||||
predicate getUseInterval(Instruction useInstr, IntValue startBitUse, IntValue endBitUse) {
|
||||
exists(VariableMemoryLocation use |
|
||||
use = getOperandMemoryLocation(useInstr.getAnOperand()) and
|
||||
startBitUse = use.getStartBitOffset() and
|
||||
endBitUse = use.getEndBitOffset()
|
||||
)
|
||||
}
|
||||
|
||||
MemoryLocation getResultMemoryLocation(Instruction instr) {
|
||||
exists(MemoryAccessKind kind, boolean isMayAccess |
|
||||
kind = instr.getResultMemoryAccess() and
|
||||
@@ -633,3 +617,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the start bit offset of a `MemoryLocation`, if any. */
|
||||
int getStartBitOffset(VariableMemoryLocation location) { result = location.getStartBitOffset() }
|
||||
|
||||
/** Gets the end bit offset of a `MemoryLocation`, if any. */
|
||||
int getEndBitOffset(VariableMemoryLocation location) { result = location.getEndBitOffset() }
|
||||
|
||||
@@ -149,6 +149,34 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
||||
*/
|
||||
cached
|
||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
|
||||
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
|
||||
oldInstruction = getOldInstruction(chi.getPartial()) and
|
||||
location = Alias::getResultMemoryLocation(oldInstruction) and
|
||||
startBitOffset = Alias::getStartBitOffset(location) and
|
||||
endBitOffset = Alias::getEndBitOffset(location)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
||||
* `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
cached
|
||||
predicate getUsedInterval(NonPhiMemoryOperand operand, int startBitOffset, int endBitOffset) {
|
||||
exists(Alias::MemoryLocation location, OldIR::NonPhiMemoryOperand oldOperand |
|
||||
oldOperand = operand.getUse().(OldInstruction).getAnOperand() and
|
||||
location = Alias::getOperandMemoryLocation(oldOperand) and
|
||||
startBitOffset = Alias::getStartBitOffset(location) and
|
||||
endBitOffset = Alias::getEndBitOffset(location)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
|
||||
@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
|
||||
* Gets the operand that represents the new value written by the memory write.
|
||||
*/
|
||||
final Instruction getPartial() { result = getPartialOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
|
||||
*/
|
||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the operand totally overlaps with its definition and consumes the
|
||||
* bit range `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
|
||||
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -182,6 +182,18 @@ Instruction getMemoryOperandDefinition(
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
||||
*/
|
||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() }
|
||||
|
||||
/**
|
||||
* Holds if the operand totally overlaps with its definition and consumes the
|
||||
* bit range `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
predicate getUsedInterval(Operand operand, int startBit, int endBit) { none() }
|
||||
|
||||
/** Gets a non-phi instruction that defines an operand of `instr`. */
|
||||
private Instruction getNonPhiOperandDef(Instruction instr) {
|
||||
result = getRegisterOperandDefinition(instr, _)
|
||||
|
||||
@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
|
||||
* Gets the operand that represents the new value written by the memory write.
|
||||
*/
|
||||
final Instruction getPartial() { result = getPartialOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
|
||||
*/
|
||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the operand totally overlaps with its definition and consumes the
|
||||
* bit range `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
|
||||
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -149,6 +149,34 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
||||
*/
|
||||
cached
|
||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
|
||||
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
|
||||
oldInstruction = getOldInstruction(chi.getPartial()) and
|
||||
location = Alias::getResultMemoryLocation(oldInstruction) and
|
||||
startBitOffset = Alias::getStartBitOffset(location) and
|
||||
endBitOffset = Alias::getEndBitOffset(location)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
||||
* `[startBitOffset, endBitOffset)`.
|
||||
*/
|
||||
cached
|
||||
predicate getUsedInterval(NonPhiMemoryOperand operand, int startBitOffset, int endBitOffset) {
|
||||
exists(Alias::MemoryLocation location, OldIR::NonPhiMemoryOperand oldOperand |
|
||||
oldOperand = operand.getUse().(OldInstruction).getAnOperand() and
|
||||
location = Alias::getOperandMemoryLocation(oldOperand) and
|
||||
startBitOffset = Alias::getStartBitOffset(location) and
|
||||
endBitOffset = Alias::getEndBitOffset(location)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
|
||||
@@ -79,3 +79,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
|
||||
MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
|
||||
result = getMemoryLocation(getAddressOperandAllocation(operand.getAddressOperand()))
|
||||
}
|
||||
|
||||
/** Gets the start bit offset of a `MemoryLocation`, if any. */
|
||||
int getStartBitOffset(MemoryLocation location) { none() }
|
||||
|
||||
/** Gets the end bit offset of a `MemoryLocation`, if any. */
|
||||
int getEndBitOffset(MemoryLocation location) { none() }
|
||||
|
||||
Reference in New Issue
Block a user