зеркало из https://github.com/github/codeql.git
C++/C#: Make `AliasedUse` access only non-local memory
The `AliasedUse` instruction is supposed to represent future uses of aliased memory after the function returns. Since local variables from that function are no longer allocated after the function returns, the `AliasedUse` instruction should access only the set of aliased locations that does not include locals from the current stack frame.
This commit is contained in:
Родитель
1223388ab6
Коммит
56cbd0c152
|
@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
|
|||
TBufferMayMemoryAccess() or
|
||||
TEscapedMemoryAccess() or
|
||||
TEscapedMayMemoryAccess() or
|
||||
TNonLocalMayMemoryAccess() or
|
||||
TPhiMemoryAccess() or
|
||||
TUnmodeledMemoryAccess() or
|
||||
TChiTotalMemoryAccess() or
|
||||
|
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
|
|||
override string toString() { result = "escaped(may)" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The operand or result may access all memory whose address has escaped, other than data on the
|
||||
* stack frame of the current function.
|
||||
*/
|
||||
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
|
||||
override string toString() { result = "nonlocal(may)" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The operand is a Phi operand, which accesses the same memory as its
|
||||
* definition.
|
||||
|
|
|
@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
|
|||
|
||||
override MemoryAccessKind getMemoryAccess() {
|
||||
useInstr instanceof AliasedUseInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
result instanceof NonLocalMayMemoryAccess
|
||||
or
|
||||
useInstr instanceof CallSideEffectInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
|
|
|
@ -35,6 +35,7 @@ private newtype TMemoryLocation =
|
|||
hasOperandMemoryAccess(_, var, type, startBitOffset, endBitOffset)
|
||||
} or
|
||||
TUnknownMemoryLocation(IRFunction irFunc) or
|
||||
TUnknownNonLocalMemoryLocation(IRFunction irFunc) or
|
||||
TUnknownVirtualVariable(IRFunction irFunc)
|
||||
|
||||
/**
|
||||
|
@ -133,6 +134,24 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
|
|||
final override string getUniqueId() { result = "{Unknown}" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to memory that is not known to be confined to a specific `IRVariable`, but is known to
|
||||
* not access memory on the current function's stack frame.
|
||||
*/
|
||||
class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation {
|
||||
IRFunction irFunc;
|
||||
|
||||
UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) }
|
||||
|
||||
final override string toString() { result = "{UnknownNonLocal}" }
|
||||
|
||||
final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) }
|
||||
|
||||
final override Type getType() { result instanceof UnknownType }
|
||||
|
||||
final override string getUniqueId() { result = "{UnknownNonLocal}" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to all aliased memory.
|
||||
*/
|
||||
|
@ -163,6 +182,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
|
|||
def instanceof UnknownMemoryLocation and
|
||||
result instanceof MayPartiallyOverlap
|
||||
or
|
||||
// An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual
|
||||
// variable, except a local variable.
|
||||
def.getVirtualVariable() = use.getVirtualVariable() and
|
||||
def instanceof UnknownNonLocalMemoryLocation and
|
||||
result instanceof MayPartiallyOverlap and
|
||||
not use.(VariableMemoryLocation).getVariable() instanceof IRAutomaticVariable
|
||||
or
|
||||
exists(VariableMemoryLocation defVariableLocation |
|
||||
defVariableLocation = def and
|
||||
(
|
||||
|
@ -171,6 +197,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
|
|||
(use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and
|
||||
result instanceof MayPartiallyOverlap
|
||||
or
|
||||
// A VariableMemoryLocation that is not a local variable may partially overlap an unknown
|
||||
// non-local location within the same virtual variable.
|
||||
def.getVirtualVariable() = use.getVirtualVariable() and
|
||||
use instanceof UnknownNonLocalMemoryLocation and
|
||||
result instanceof MayPartiallyOverlap and
|
||||
not defVariableLocation.getVariable() instanceof IRAutomaticVariable
|
||||
or
|
||||
// A VariableMemoryLocation overlaps another location within the same variable based on the relationship
|
||||
// of the two offset intervals.
|
||||
exists(Overlap intervalOverlap |
|
||||
|
@ -296,6 +329,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
|
|||
or
|
||||
kind instanceof EscapedMayMemoryAccess and
|
||||
result = TUnknownMemoryLocation(instr.getEnclosingIRFunction())
|
||||
or
|
||||
kind instanceof NonLocalMayMemoryAccess and
|
||||
result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -320,6 +356,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
|
|||
or
|
||||
kind instanceof EscapedMayMemoryAccess and
|
||||
result = TUnknownMemoryLocation(operand.getEnclosingIRFunction())
|
||||
or
|
||||
kind instanceof NonLocalMayMemoryAccess and
|
||||
result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
|
|||
|
||||
override MemoryAccessKind getMemoryAccess() {
|
||||
useInstr instanceof AliasedUseInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
result instanceof NonLocalMayMemoryAccess
|
||||
or
|
||||
useInstr instanceof CallSideEffectInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
|
|
|
@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
|
|||
|
||||
override MemoryAccessKind getMemoryAccess() {
|
||||
useInstr instanceof AliasedUseInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
result instanceof NonLocalMayMemoryAccess
|
||||
or
|
||||
useInstr instanceof CallSideEffectInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
|
|
|
@ -340,7 +340,7 @@ ssa.cpp:
|
|||
# 98| v0_19(void) = NoOp :
|
||||
# 95| v0_20(void) = ReturnVoid :
|
||||
# 95| v0_21(void) = UnmodeledUse : mu*
|
||||
# 95| v0_22(void) = AliasedUse : ~m0_18
|
||||
# 95| v0_22(void) = AliasedUse : ~m0_15
|
||||
# 95| v0_23(void) = ExitFunction :
|
||||
|
||||
# 100| void MustTotallyOverlap(Point)
|
||||
|
@ -396,7 +396,7 @@ ssa.cpp:
|
|||
# 109| v0_25(void) = NoOp :
|
||||
# 105| v0_26(void) = ReturnVoid :
|
||||
# 105| v0_27(void) = UnmodeledUse : mu*
|
||||
# 105| v0_28(void) = AliasedUse : ~m0_24
|
||||
# 105| v0_28(void) = AliasedUse : ~m0_21
|
||||
# 105| v0_29(void) = ExitFunction :
|
||||
|
||||
# 111| void MayPartiallyOverlap(int, int)
|
||||
|
@ -468,7 +468,7 @@ ssa.cpp:
|
|||
# 120| v0_33(void) = NoOp :
|
||||
# 116| v0_34(void) = ReturnVoid :
|
||||
# 116| v0_35(void) = UnmodeledUse : mu*
|
||||
# 116| v0_36(void) = AliasedUse : ~m0_32
|
||||
# 116| v0_36(void) = AliasedUse : ~m0_29
|
||||
# 116| v0_37(void) = ExitFunction :
|
||||
|
||||
# 122| void MergeMustExactlyOverlap(bool, int, int)
|
||||
|
@ -865,5 +865,5 @@ ssa.cpp:
|
|||
# 207| r0_23(glval<int>) = VariableAddress[#return] :
|
||||
# 207| v0_24(void) = ReturnValue : &:r0_23, m0_22
|
||||
# 207| v0_25(void) = UnmodeledUse : mu*
|
||||
# 207| v0_26(void) = AliasedUse : ~m0_18
|
||||
# 207| v0_26(void) = AliasedUse : ~m0_1
|
||||
# 207| v0_27(void) = ExitFunction :
|
||||
|
|
|
@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
|
|||
TBufferMayMemoryAccess() or
|
||||
TEscapedMemoryAccess() or
|
||||
TEscapedMayMemoryAccess() or
|
||||
TNonLocalMayMemoryAccess() or
|
||||
TPhiMemoryAccess() or
|
||||
TUnmodeledMemoryAccess() or
|
||||
TChiTotalMemoryAccess() or
|
||||
|
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
|
|||
override string toString() { result = "escaped(may)" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The operand or result may access all memory whose address has escaped, other than data on the
|
||||
* stack frame of the current function.
|
||||
*/
|
||||
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
|
||||
override string toString() { result = "nonlocal(may)" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The operand is a Phi operand, which accesses the same memory as its
|
||||
* definition.
|
||||
|
|
|
@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
|
|||
|
||||
override MemoryAccessKind getMemoryAccess() {
|
||||
useInstr instanceof AliasedUseInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
result instanceof NonLocalMayMemoryAccess
|
||||
or
|
||||
useInstr instanceof CallSideEffectInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
|
|
|
@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
|
|||
|
||||
override MemoryAccessKind getMemoryAccess() {
|
||||
useInstr instanceof AliasedUseInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
result instanceof NonLocalMayMemoryAccess
|
||||
or
|
||||
useInstr instanceof CallSideEffectInstruction and
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
|
|
Загрузка…
Ссылка в новой задаче