C++: add indexes for specific side effects

This commit is contained in:
Robert Marsh
2019-09-17 16:41:23 -07:00
parent 24574be007
commit 8649978a43
18 changed files with 966 additions and 784 deletions

View File

@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
final string getValue() { result = value } final string getValue() { result = value }
} }
class IndexedInstruction extends Instruction {
int index;
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
final override string getImmediateString() { result = index.toString() }
final int getIndex() { result = index }
}
class EnterFunctionInstruction extends Instruction { class EnterFunctionInstruction extends Instruction {
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction } EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
} }

View File

@@ -342,6 +342,11 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField() result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField()
} }
cached
int getInstructionIndex(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::IndexedInstruction).getIndex()
}
cached cached
Function getInstructionFunction(Instruction instruction) { Function getInstructionFunction(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol() result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol()

View File

@@ -72,6 +72,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override int getSortOrder() { result = 1 } final override int getSortOrder() { result = 1 }
} }
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
/** /**
* The operand representing the read side effect of a `SideEffectInstruction`. * The operand representing the read side effect of a `SideEffectInstruction`.
*/ */

View File

@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
final string getValue() { result = value } final string getValue() { result = value }
} }
class IndexedInstruction extends Instruction {
int index;
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
final override string getImmediateString() { result = index.toString() }
final int getIndex() { result = index }
}
class EnterFunctionInstruction extends Instruction { class EnterFunctionInstruction extends Instruction {
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction } EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
} }

View File

@@ -259,6 +259,14 @@ private module Cached {
.getInstructionConstantValue(getInstructionTag(instruction)) .getInstructionConstantValue(getInstructionTag(instruction))
} }
cached
int getInstructionIndex(Instruction instruction) {
exists(TranslatedElement element, InstructionTag tag |
instructionOrigin(instruction, element, tag) and
result = element.getInstructionIndex(tag)
)
}
cached cached
StringLiteral getInstructionStringLiteral(Instruction instruction) { StringLiteral getInstructionStringLiteral(Instruction instruction) {
result = getInstructionTranslatedElement(instruction) result = getInstructionTranslatedElement(instruction)

View File

@@ -456,6 +456,12 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
operandTag instanceof SideEffectOperandTag and operandTag instanceof SideEffectOperandTag and
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, _) and call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, _) and
result = getEnclosingFunction().getUnmodeledDefinitionInstruction() result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
or
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
result = getTranslatedExpr(call
.getArgument(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index)).getFullyConverted())
.getResult()
} }
override Type getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) { override Type getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
@@ -471,15 +477,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
predicate hasSpecificWriteSideEffect(Opcode op) { predicate hasSpecificWriteSideEffect(Opcode op) {
exists(boolean buffer, boolean mustWrite | exists(boolean buffer, boolean mustWrite |
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
( then
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, true, mustWrite) and
or buffer = true and
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect (
or mustWrite = false and op instanceof Opcode::SizedBufferMayWriteSideEffect
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect or
or mustWrite = true and op instanceof Opcode::SizedBufferMustWriteSideEffect
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect )
else (
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and
(
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect
or
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect
or
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect
or
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect
)
) )
) )
or or
@@ -495,7 +512,9 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
predicate hasSpecificReadSideEffect(Opcode op) { predicate hasSpecificReadSideEffect(Opcode op) {
exists(boolean buffer | exists(boolean buffer |
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and
( if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
then buffer = true and op instanceof Opcode::SizedBufferReadSideEffect
else (
buffer = true and op instanceof Opcode::BufferReadSideEffect buffer = true and op instanceof Opcode::BufferReadSideEffect
or or
buffer = false and op instanceof Opcode::IndirectReadSideEffect buffer = false and op instanceof Opcode::IndirectReadSideEffect
@@ -506,6 +525,11 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
op instanceof Opcode::IndirectReadSideEffect op instanceof Opcode::IndirectReadSideEffect
} }
final override int getInstructionIndex(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = index
}
/** /**
* Gets the `TranslatedFunction` containing this expression. * Gets the `TranslatedFunction` containing this expression.
*/ */

View File

@@ -600,6 +600,12 @@ abstract class TranslatedElement extends TTranslatedElement {
*/ */
string getInstructionConstantValue(InstructionTag tag) { none() } string getInstructionConstantValue(InstructionTag tag) { none() }
/**
* If the instruction specified by `tag` is an `IndexedInstruction`, gets the
* index for that instruction.
*/
int getInstructionIndex(InstructionTag tag) { none() }
/** /**
* If the instruction specified by `tag` is a `PointerArithmeticInstruction`, * If the instruction specified by `tag` is a `PointerArithmeticInstruction`,
* gets the size of the type pointed to by the pointer. * gets the size of the type pointed to by the pointer.

View File

@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
final string getValue() { result = value } final string getValue() { result = value }
} }
class IndexedInstruction extends Instruction {
int index;
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
final override string getImmediateString() { result = index.toString() }
final int getIndex() { result = index }
}
class EnterFunctionInstruction extends Instruction { class EnterFunctionInstruction extends Instruction {
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction } EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
} }

View File

@@ -342,6 +342,11 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField() result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField()
} }
cached
int getInstructionIndex(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::IndexedInstruction).getIndex()
}
cached cached
Function getInstructionFunction(Instruction instruction) { Function getInstructionFunction(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol() result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol()

View File

@@ -57,5 +57,12 @@ class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 1 and buffer = true i = 1 and buffer = true
} }
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
result = 2 and
(
i = 0 or
i = 1
)
}
}

View File

@@ -34,5 +34,7 @@ abstract class SideEffectFunction extends Function {
} }
predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { none() } predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { none() }
}
// TODO: name?
ParameterIndex getParameterSizeIndex(ParameterIndex i) { none() }
}

File diff suppressed because it is too large Load Diff

View File

@@ -311,29 +311,29 @@ ssa.cpp:
# 95| void MustExactlyOverlapEscaped(Point) # 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0 # 95| Block 0
# 95| v0_0(void) = EnterFunction : # 95| v0_0(void) = EnterFunction :
# 95| m0_1(unknown) = AliasedDefinition : # 95| m0_1(unknown) = AliasedDefinition :
# 95| mu0_2(unknown) = UnmodeledDefinition : # 95| mu0_2(unknown) = UnmodeledDefinition :
# 95| r0_3(glval<Point>) = VariableAddress[a] : # 95| r0_3(glval<Point>) = VariableAddress[a] :
# 95| m0_4(Point) = InitializeParameter[a] : &:r0_3 # 95| m0_4(Point) = InitializeParameter[a] : &:r0_3
# 95| m0_5(unknown) = Chi : total:m0_1, partial:m0_4 # 95| m0_5(unknown) = Chi : total:m0_1, partial:m0_4
# 96| r0_6(glval<Point>) = VariableAddress[b] : # 96| r0_6(glval<Point>) = VariableAddress[b] :
# 96| r0_7(glval<Point>) = VariableAddress[a] : # 96| r0_7(glval<Point>) = VariableAddress[a] :
# 96| r0_8(Point) = Load : &:r0_7, m0_4 # 96| r0_8(Point) = Load : &:r0_7, m0_4
# 96| m0_9(Point) = Store : &:r0_6, r0_8 # 96| m0_9(Point) = Store : &:r0_6, r0_8
# 97| r0_10(glval<unknown>) = FunctionAddress[Escape] : # 97| r0_10(glval<unknown>) = FunctionAddress[Escape] :
# 97| r0_11(glval<Point>) = VariableAddress[a] : # 97| r0_11(glval<Point>) = VariableAddress[a] :
# 97| r0_12(void *) = Convert : r0_11 # 97| r0_12(void *) = Convert : r0_11
# 97| v0_13(void) = Call : func:r0_10, 0:r0_12 # 97| v0_13(void) = Call : func:r0_10, 0:r0_12
# 97| m0_14(unknown) = ^CallSideEffect : ~m0_5 # 97| m0_14(unknown) = ^CallSideEffect : ~m0_5
# 97| m0_15(unknown) = Chi : total:m0_5, partial:m0_14 # 97| m0_15(unknown) = Chi : total:m0_5, partial:m0_14
# 97| v0_16(void) = ^IndirectReadSideEffect : &:r0_12, ~m0_15 # 97| v0_16(void) = ^IndirectReadSideEffect[0] : &:r0_12, ~m0_15
# 97| m0_17(unknown) = ^BufferMayWriteSideEffect : &:r0_12, ~m0_15 # 97| m0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_12, ~m0_15
# 97| m0_18(unknown) = Chi : total:m0_15, partial:m0_17 # 97| m0_18(unknown) = Chi : total:m0_15, partial:m0_17
# 98| v0_19(void) = NoOp : # 98| v0_19(void) = NoOp :
# 95| v0_20(void) = ReturnVoid : # 95| v0_20(void) = ReturnVoid :
# 95| v0_21(void) = UnmodeledUse : mu* # 95| v0_21(void) = UnmodeledUse : mu*
# 95| v0_22(void) = ExitFunction : # 95| v0_22(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point) # 100| void MustTotallyOverlap(Point)
# 100| Block 0 # 100| Block 0
@@ -359,35 +359,35 @@ ssa.cpp:
# 105| void MustTotallyOverlapEscaped(Point) # 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0 # 105| Block 0
# 105| v0_0(void) = EnterFunction : # 105| v0_0(void) = EnterFunction :
# 105| m0_1(unknown) = AliasedDefinition : # 105| m0_1(unknown) = AliasedDefinition :
# 105| mu0_2(unknown) = UnmodeledDefinition : # 105| mu0_2(unknown) = UnmodeledDefinition :
# 105| r0_3(glval<Point>) = VariableAddress[a] : # 105| r0_3(glval<Point>) = VariableAddress[a] :
# 105| m0_4(Point) = InitializeParameter[a] : &:r0_3 # 105| m0_4(Point) = InitializeParameter[a] : &:r0_3
# 105| m0_5(unknown) = Chi : total:m0_1, partial:m0_4 # 105| m0_5(unknown) = Chi : total:m0_1, partial:m0_4
# 106| r0_6(glval<int>) = VariableAddress[x] : # 106| r0_6(glval<int>) = VariableAddress[x] :
# 106| r0_7(glval<Point>) = VariableAddress[a] : # 106| r0_7(glval<Point>) = VariableAddress[a] :
# 106| r0_8(glval<int>) = FieldAddress[x] : r0_7 # 106| r0_8(glval<int>) = FieldAddress[x] : r0_7
# 106| r0_9(int) = Load : &:r0_8, ~m0_4 # 106| r0_9(int) = Load : &:r0_8, ~m0_4
# 106| m0_10(int) = Store : &:r0_6, r0_9 # 106| m0_10(int) = Store : &:r0_6, r0_9
# 107| r0_11(glval<int>) = VariableAddress[y] : # 107| r0_11(glval<int>) = VariableAddress[y] :
# 107| r0_12(glval<Point>) = VariableAddress[a] : # 107| r0_12(glval<Point>) = VariableAddress[a] :
# 107| r0_13(glval<int>) = FieldAddress[y] : r0_12 # 107| r0_13(glval<int>) = FieldAddress[y] : r0_12
# 107| r0_14(int) = Load : &:r0_13, ~m0_4 # 107| r0_14(int) = Load : &:r0_13, ~m0_4
# 107| m0_15(int) = Store : &:r0_11, r0_14 # 107| m0_15(int) = Store : &:r0_11, r0_14
# 108| r0_16(glval<unknown>) = FunctionAddress[Escape] : # 108| r0_16(glval<unknown>) = FunctionAddress[Escape] :
# 108| r0_17(glval<Point>) = VariableAddress[a] : # 108| r0_17(glval<Point>) = VariableAddress[a] :
# 108| r0_18(void *) = Convert : r0_17 # 108| r0_18(void *) = Convert : r0_17
# 108| v0_19(void) = Call : func:r0_16, 0:r0_18 # 108| v0_19(void) = Call : func:r0_16, 0:r0_18
# 108| m0_20(unknown) = ^CallSideEffect : ~m0_5 # 108| m0_20(unknown) = ^CallSideEffect : ~m0_5
# 108| m0_21(unknown) = Chi : total:m0_5, partial:m0_20 # 108| m0_21(unknown) = Chi : total:m0_5, partial:m0_20
# 108| v0_22(void) = ^IndirectReadSideEffect : &:r0_18, ~m0_21 # 108| v0_22(void) = ^IndirectReadSideEffect[0] : &:r0_18, ~m0_21
# 108| m0_23(unknown) = ^BufferMayWriteSideEffect : &:r0_18, ~m0_21 # 108| m0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_18, ~m0_21
# 108| m0_24(unknown) = Chi : total:m0_21, partial:m0_23 # 108| m0_24(unknown) = Chi : total:m0_21, partial:m0_23
# 109| v0_25(void) = NoOp : # 109| v0_25(void) = NoOp :
# 105| v0_26(void) = ReturnVoid : # 105| v0_26(void) = ReturnVoid :
# 105| v0_27(void) = UnmodeledUse : mu* # 105| v0_27(void) = UnmodeledUse : mu*
# 105| v0_28(void) = ExitFunction : # 105| v0_28(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int) # 111| void MayPartiallyOverlap(int, int)
# 111| Block 0 # 111| Block 0
@@ -421,43 +421,43 @@ ssa.cpp:
# 116| void MayPartiallyOverlapEscaped(int, int) # 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0 # 116| Block 0
# 116| v0_0(void) = EnterFunction : # 116| v0_0(void) = EnterFunction :
# 116| m0_1(unknown) = AliasedDefinition : # 116| m0_1(unknown) = AliasedDefinition :
# 116| mu0_2(unknown) = UnmodeledDefinition : # 116| mu0_2(unknown) = UnmodeledDefinition :
# 116| r0_3(glval<int>) = VariableAddress[x] : # 116| r0_3(glval<int>) = VariableAddress[x] :
# 116| m0_4(int) = InitializeParameter[x] : &:r0_3 # 116| m0_4(int) = InitializeParameter[x] : &:r0_3
# 116| r0_5(glval<int>) = VariableAddress[y] : # 116| r0_5(glval<int>) = VariableAddress[y] :
# 116| m0_6(int) = InitializeParameter[y] : &:r0_5 # 116| m0_6(int) = InitializeParameter[y] : &:r0_5
# 117| r0_7(glval<Point>) = VariableAddress[a] : # 117| r0_7(glval<Point>) = VariableAddress[a] :
# 117| m0_8(Point) = Uninitialized[a] : &:r0_7 # 117| m0_8(Point) = Uninitialized[a] : &:r0_7
# 117| m0_9(unknown) = Chi : total:m0_1, partial:m0_8 # 117| m0_9(unknown) = Chi : total:m0_1, partial:m0_8
# 117| r0_10(glval<int>) = FieldAddress[x] : r0_7 # 117| r0_10(glval<int>) = FieldAddress[x] : r0_7
# 117| r0_11(glval<int>) = VariableAddress[x] : # 117| r0_11(glval<int>) = VariableAddress[x] :
# 117| r0_12(int) = Load : &:r0_11, m0_4 # 117| r0_12(int) = Load : &:r0_11, m0_4
# 117| m0_13(int) = Store : &:r0_10, r0_12 # 117| m0_13(int) = Store : &:r0_10, r0_12
# 117| m0_14(unknown) = Chi : total:m0_9, partial:m0_13 # 117| m0_14(unknown) = Chi : total:m0_9, partial:m0_13
# 117| r0_15(glval<int>) = FieldAddress[y] : r0_7 # 117| r0_15(glval<int>) = FieldAddress[y] : r0_7
# 117| r0_16(glval<int>) = VariableAddress[y] : # 117| r0_16(glval<int>) = VariableAddress[y] :
# 117| r0_17(int) = Load : &:r0_16, m0_6 # 117| r0_17(int) = Load : &:r0_16, m0_6
# 117| m0_18(int) = Store : &:r0_15, r0_17 # 117| m0_18(int) = Store : &:r0_15, r0_17
# 117| m0_19(unknown) = Chi : total:m0_14, partial:m0_18 # 117| m0_19(unknown) = Chi : total:m0_14, partial:m0_18
# 118| r0_20(glval<Point>) = VariableAddress[b] : # 118| r0_20(glval<Point>) = VariableAddress[b] :
# 118| r0_21(glval<Point>) = VariableAddress[a] : # 118| r0_21(glval<Point>) = VariableAddress[a] :
# 118| r0_22(Point) = Load : &:r0_21, ~m0_19 # 118| r0_22(Point) = Load : &:r0_21, ~m0_19
# 118| m0_23(Point) = Store : &:r0_20, r0_22 # 118| m0_23(Point) = Store : &:r0_20, r0_22
# 119| r0_24(glval<unknown>) = FunctionAddress[Escape] : # 119| r0_24(glval<unknown>) = FunctionAddress[Escape] :
# 119| r0_25(glval<Point>) = VariableAddress[a] : # 119| r0_25(glval<Point>) = VariableAddress[a] :
# 119| r0_26(void *) = Convert : r0_25 # 119| r0_26(void *) = Convert : r0_25
# 119| v0_27(void) = Call : func:r0_24, 0:r0_26 # 119| v0_27(void) = Call : func:r0_24, 0:r0_26
# 119| m0_28(unknown) = ^CallSideEffect : ~m0_19 # 119| m0_28(unknown) = ^CallSideEffect : ~m0_19
# 119| m0_29(unknown) = Chi : total:m0_19, partial:m0_28 # 119| m0_29(unknown) = Chi : total:m0_19, partial:m0_28
# 119| v0_30(void) = ^IndirectReadSideEffect : &:r0_26, ~m0_29 # 119| v0_30(void) = ^IndirectReadSideEffect[0] : &:r0_26, ~m0_29
# 119| m0_31(unknown) = ^BufferMayWriteSideEffect : &:r0_26, ~m0_29 # 119| m0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_26, ~m0_29
# 119| m0_32(unknown) = Chi : total:m0_29, partial:m0_31 # 119| m0_32(unknown) = Chi : total:m0_29, partial:m0_31
# 120| v0_33(void) = NoOp : # 120| v0_33(void) = NoOp :
# 116| v0_34(void) = ReturnVoid : # 116| v0_34(void) = ReturnVoid :
# 116| v0_35(void) = UnmodeledUse : mu* # 116| v0_35(void) = UnmodeledUse : mu*
# 116| v0_36(void) = ExitFunction : # 116| v0_36(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int) # 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0 # 122| Block 0
@@ -819,30 +819,30 @@ ssa.cpp:
# 207| int ModeledCallTarget(int) # 207| int ModeledCallTarget(int)
# 207| Block 0 # 207| Block 0
# 207| v0_0(void) = EnterFunction : # 207| v0_0(void) = EnterFunction :
# 207| m0_1(unknown) = AliasedDefinition : # 207| m0_1(unknown) = AliasedDefinition :
# 207| mu0_2(unknown) = UnmodeledDefinition : # 207| mu0_2(unknown) = UnmodeledDefinition :
# 207| r0_3(glval<int>) = VariableAddress[x] : # 207| r0_3(glval<int>) = VariableAddress[x] :
# 207| m0_4(int) = InitializeParameter[x] : &:r0_3 # 207| m0_4(int) = InitializeParameter[x] : &:r0_3
# 207| m0_5(unknown) = Chi : total:m0_1, partial:m0_4 # 207| m0_5(unknown) = Chi : total:m0_1, partial:m0_4
# 208| r0_6(glval<int>) = VariableAddress[y] : # 208| r0_6(glval<int>) = VariableAddress[y] :
# 208| m0_7(int) = Uninitialized[y] : &:r0_6 # 208| m0_7(int) = Uninitialized[y] : &:r0_6
# 208| m0_8(unknown) = Chi : total:m0_5, partial:m0_7 # 208| m0_8(unknown) = Chi : total:m0_5, partial:m0_7
# 209| r0_9(glval<unknown>) = FunctionAddress[memcpy] : # 209| r0_9(glval<unknown>) = FunctionAddress[memcpy] :
# 209| r0_10(glval<int>) = VariableAddress[y] : # 209| r0_10(glval<int>) = VariableAddress[y] :
# 209| r0_11(void *) = Convert : r0_10 # 209| r0_11(void *) = Convert : r0_10
# 209| r0_12(glval<int>) = VariableAddress[x] : # 209| r0_12(glval<int>) = VariableAddress[x] :
# 209| r0_13(void *) = Convert : r0_12 # 209| r0_13(void *) = Convert : r0_12
# 209| r0_14(int) = Constant[4] : # 209| r0_14(int) = Constant[4] :
# 209| r0_15(void *) = Call : func:r0_9, 0:r0_11, 1:r0_13, 2:r0_14 # 209| r0_15(void *) = Call : func:r0_9, 0:r0_11, 1:r0_13, 2:r0_14
# 209| v0_16(void) = ^BufferReadSideEffect : &:r0_13, ~m0_4 # 209| v0_16(void) = ^SizedBufferReadSideEffect[1] : &:r0_13, r0_14, ~mu0_2
# 209| m0_17(unknown) = ^BufferMustWriteSideEffect : &:r0_11 # 209| m0_17(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_11, r0_14
# 209| m0_18(unknown) = Chi : total:m0_8, partial:m0_17 # 209| m0_18(unknown) = Chi : total:m0_8, partial:m0_17
# 210| r0_19(glval<int>) = VariableAddress[#return] : # 210| r0_19(glval<int>) = VariableAddress[#return] :
# 210| r0_20(glval<int>) = VariableAddress[y] : # 210| r0_20(glval<int>) = VariableAddress[y] :
# 210| r0_21(int) = Load : &:r0_20, ~m0_18 # 210| r0_21(int) = Load : &:r0_20, ~m0_18
# 210| m0_22(int) = Store : &:r0_19, r0_21 # 210| m0_22(int) = Store : &:r0_19, r0_21
# 207| r0_23(glval<int>) = VariableAddress[#return] : # 207| r0_23(glval<int>) = VariableAddress[#return] :
# 207| v0_24(void) = ReturnValue : &:r0_23, m0_22 # 207| v0_24(void) = ReturnValue : &:r0_23, m0_22
# 207| v0_25(void) = UnmodeledUse : mu* # 207| v0_25(void) = UnmodeledUse : mu*
# 207| v0_26(void) = ExitFunction : # 207| v0_26(void) = ExitFunction :

View File

@@ -312,26 +312,26 @@ ssa.cpp:
# 95| void MustExactlyOverlapEscaped(Point) # 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0 # 95| Block 0
# 95| v0_0(void) = EnterFunction : # 95| v0_0(void) = EnterFunction :
# 95| mu0_1(unknown) = AliasedDefinition : # 95| mu0_1(unknown) = AliasedDefinition :
# 95| mu0_2(unknown) = UnmodeledDefinition : # 95| mu0_2(unknown) = UnmodeledDefinition :
# 95| r0_3(glval<Point>) = VariableAddress[a] : # 95| r0_3(glval<Point>) = VariableAddress[a] :
# 95| mu0_4(Point) = InitializeParameter[a] : &:r0_3 # 95| mu0_4(Point) = InitializeParameter[a] : &:r0_3
# 96| r0_5(glval<Point>) = VariableAddress[b] : # 96| r0_5(glval<Point>) = VariableAddress[b] :
# 96| r0_6(glval<Point>) = VariableAddress[a] : # 96| r0_6(glval<Point>) = VariableAddress[a] :
# 96| r0_7(Point) = Load : &:r0_6, ~mu0_2 # 96| r0_7(Point) = Load : &:r0_6, ~mu0_2
# 96| m0_8(Point) = Store : &:r0_5, r0_7 # 96| m0_8(Point) = Store : &:r0_5, r0_7
# 97| r0_9(glval<unknown>) = FunctionAddress[Escape] : # 97| r0_9(glval<unknown>) = FunctionAddress[Escape] :
# 97| r0_10(glval<Point>) = VariableAddress[a] : # 97| r0_10(glval<Point>) = VariableAddress[a] :
# 97| r0_11(void *) = Convert : r0_10 # 97| r0_11(void *) = Convert : r0_10
# 97| v0_12(void) = Call : func:r0_9, 0:r0_11 # 97| v0_12(void) = Call : func:r0_9, 0:r0_11
# 97| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 # 97| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
# 97| v0_14(void) = ^IndirectReadSideEffect : &:r0_11, ~mu0_2 # 97| v0_14(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
# 97| mu0_15(unknown) = ^BufferMayWriteSideEffect : &:r0_11, ~mu0_2 # 97| mu0_15(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11, ~mu0_2
# 98| v0_16(void) = NoOp : # 98| v0_16(void) = NoOp :
# 95| v0_17(void) = ReturnVoid : # 95| v0_17(void) = ReturnVoid :
# 95| v0_18(void) = UnmodeledUse : mu* # 95| v0_18(void) = UnmodeledUse : mu*
# 95| v0_19(void) = ExitFunction : # 95| v0_19(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point) # 100| void MustTotallyOverlap(Point)
# 100| Block 0 # 100| Block 0
@@ -357,32 +357,32 @@ ssa.cpp:
# 105| void MustTotallyOverlapEscaped(Point) # 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0 # 105| Block 0
# 105| v0_0(void) = EnterFunction : # 105| v0_0(void) = EnterFunction :
# 105| mu0_1(unknown) = AliasedDefinition : # 105| mu0_1(unknown) = AliasedDefinition :
# 105| mu0_2(unknown) = UnmodeledDefinition : # 105| mu0_2(unknown) = UnmodeledDefinition :
# 105| r0_3(glval<Point>) = VariableAddress[a] : # 105| r0_3(glval<Point>) = VariableAddress[a] :
# 105| mu0_4(Point) = InitializeParameter[a] : &:r0_3 # 105| mu0_4(Point) = InitializeParameter[a] : &:r0_3
# 106| r0_5(glval<int>) = VariableAddress[x] : # 106| r0_5(glval<int>) = VariableAddress[x] :
# 106| r0_6(glval<Point>) = VariableAddress[a] : # 106| r0_6(glval<Point>) = VariableAddress[a] :
# 106| r0_7(glval<int>) = FieldAddress[x] : r0_6 # 106| r0_7(glval<int>) = FieldAddress[x] : r0_6
# 106| r0_8(int) = Load : &:r0_7, ~mu0_2 # 106| r0_8(int) = Load : &:r0_7, ~mu0_2
# 106| m0_9(int) = Store : &:r0_5, r0_8 # 106| m0_9(int) = Store : &:r0_5, r0_8
# 107| r0_10(glval<int>) = VariableAddress[y] : # 107| r0_10(glval<int>) = VariableAddress[y] :
# 107| r0_11(glval<Point>) = VariableAddress[a] : # 107| r0_11(glval<Point>) = VariableAddress[a] :
# 107| r0_12(glval<int>) = FieldAddress[y] : r0_11 # 107| r0_12(glval<int>) = FieldAddress[y] : r0_11
# 107| r0_13(int) = Load : &:r0_12, ~mu0_2 # 107| r0_13(int) = Load : &:r0_12, ~mu0_2
# 107| m0_14(int) = Store : &:r0_10, r0_13 # 107| m0_14(int) = Store : &:r0_10, r0_13
# 108| r0_15(glval<unknown>) = FunctionAddress[Escape] : # 108| r0_15(glval<unknown>) = FunctionAddress[Escape] :
# 108| r0_16(glval<Point>) = VariableAddress[a] : # 108| r0_16(glval<Point>) = VariableAddress[a] :
# 108| r0_17(void *) = Convert : r0_16 # 108| r0_17(void *) = Convert : r0_16
# 108| v0_18(void) = Call : func:r0_15, 0:r0_17 # 108| v0_18(void) = Call : func:r0_15, 0:r0_17
# 108| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 # 108| mu0_19(unknown) = ^CallSideEffect : ~mu0_2
# 108| v0_20(void) = ^IndirectReadSideEffect : &:r0_17, ~mu0_2 # 108| v0_20(void) = ^IndirectReadSideEffect[0] : &:r0_17, ~mu0_2
# 108| mu0_21(unknown) = ^BufferMayWriteSideEffect : &:r0_17, ~mu0_2 # 108| mu0_21(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17, ~mu0_2
# 109| v0_22(void) = NoOp : # 109| v0_22(void) = NoOp :
# 105| v0_23(void) = ReturnVoid : # 105| v0_23(void) = ReturnVoid :
# 105| v0_24(void) = UnmodeledUse : mu* # 105| v0_24(void) = UnmodeledUse : mu*
# 105| v0_25(void) = ExitFunction : # 105| v0_25(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int) # 111| void MayPartiallyOverlap(int, int)
# 111| Block 0 # 111| Block 0
@@ -414,38 +414,38 @@ ssa.cpp:
# 116| void MayPartiallyOverlapEscaped(int, int) # 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0 # 116| Block 0
# 116| v0_0(void) = EnterFunction : # 116| v0_0(void) = EnterFunction :
# 116| mu0_1(unknown) = AliasedDefinition : # 116| mu0_1(unknown) = AliasedDefinition :
# 116| mu0_2(unknown) = UnmodeledDefinition : # 116| mu0_2(unknown) = UnmodeledDefinition :
# 116| r0_3(glval<int>) = VariableAddress[x] : # 116| r0_3(glval<int>) = VariableAddress[x] :
# 116| m0_4(int) = InitializeParameter[x] : &:r0_3 # 116| m0_4(int) = InitializeParameter[x] : &:r0_3
# 116| r0_5(glval<int>) = VariableAddress[y] : # 116| r0_5(glval<int>) = VariableAddress[y] :
# 116| m0_6(int) = InitializeParameter[y] : &:r0_5 # 116| m0_6(int) = InitializeParameter[y] : &:r0_5
# 117| r0_7(glval<Point>) = VariableAddress[a] : # 117| r0_7(glval<Point>) = VariableAddress[a] :
# 117| mu0_8(Point) = Uninitialized[a] : &:r0_7 # 117| mu0_8(Point) = Uninitialized[a] : &:r0_7
# 117| r0_9(glval<int>) = FieldAddress[x] : r0_7 # 117| r0_9(glval<int>) = FieldAddress[x] : r0_7
# 117| r0_10(glval<int>) = VariableAddress[x] : # 117| r0_10(glval<int>) = VariableAddress[x] :
# 117| r0_11(int) = Load : &:r0_10, m0_4 # 117| r0_11(int) = Load : &:r0_10, m0_4
# 117| mu0_12(int) = Store : &:r0_9, r0_11 # 117| mu0_12(int) = Store : &:r0_9, r0_11
# 117| r0_13(glval<int>) = FieldAddress[y] : r0_7 # 117| r0_13(glval<int>) = FieldAddress[y] : r0_7
# 117| r0_14(glval<int>) = VariableAddress[y] : # 117| r0_14(glval<int>) = VariableAddress[y] :
# 117| r0_15(int) = Load : &:r0_14, m0_6 # 117| r0_15(int) = Load : &:r0_14, m0_6
# 117| mu0_16(int) = Store : &:r0_13, r0_15 # 117| mu0_16(int) = Store : &:r0_13, r0_15
# 118| r0_17(glval<Point>) = VariableAddress[b] : # 118| r0_17(glval<Point>) = VariableAddress[b] :
# 118| r0_18(glval<Point>) = VariableAddress[a] : # 118| r0_18(glval<Point>) = VariableAddress[a] :
# 118| r0_19(Point) = Load : &:r0_18, ~mu0_2 # 118| r0_19(Point) = Load : &:r0_18, ~mu0_2
# 118| m0_20(Point) = Store : &:r0_17, r0_19 # 118| m0_20(Point) = Store : &:r0_17, r0_19
# 119| r0_21(glval<unknown>) = FunctionAddress[Escape] : # 119| r0_21(glval<unknown>) = FunctionAddress[Escape] :
# 119| r0_22(glval<Point>) = VariableAddress[a] : # 119| r0_22(glval<Point>) = VariableAddress[a] :
# 119| r0_23(void *) = Convert : r0_22 # 119| r0_23(void *) = Convert : r0_22
# 119| v0_24(void) = Call : func:r0_21, 0:r0_23 # 119| v0_24(void) = Call : func:r0_21, 0:r0_23
# 119| mu0_25(unknown) = ^CallSideEffect : ~mu0_2 # 119| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
# 119| v0_26(void) = ^IndirectReadSideEffect : &:r0_23, ~mu0_2 # 119| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
# 119| mu0_27(unknown) = ^BufferMayWriteSideEffect : &:r0_23, ~mu0_2 # 119| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23, ~mu0_2
# 120| v0_28(void) = NoOp : # 120| v0_28(void) = NoOp :
# 116| v0_29(void) = ReturnVoid : # 116| v0_29(void) = ReturnVoid :
# 116| v0_30(void) = UnmodeledUse : mu* # 116| v0_30(void) = UnmodeledUse : mu*
# 116| v0_31(void) = ExitFunction : # 116| v0_31(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int) # 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0 # 122| Block 0
@@ -782,27 +782,27 @@ ssa.cpp:
# 207| int ModeledCallTarget(int) # 207| int ModeledCallTarget(int)
# 207| Block 0 # 207| Block 0
# 207| v0_0(void) = EnterFunction : # 207| v0_0(void) = EnterFunction :
# 207| mu0_1(unknown) = AliasedDefinition : # 207| mu0_1(unknown) = AliasedDefinition :
# 207| mu0_2(unknown) = UnmodeledDefinition : # 207| mu0_2(unknown) = UnmodeledDefinition :
# 207| r0_3(glval<int>) = VariableAddress[x] : # 207| r0_3(glval<int>) = VariableAddress[x] :
# 207| mu0_4(int) = InitializeParameter[x] : &:r0_3 # 207| mu0_4(int) = InitializeParameter[x] : &:r0_3
# 208| r0_5(glval<int>) = VariableAddress[y] : # 208| r0_5(glval<int>) = VariableAddress[y] :
# 208| mu0_6(int) = Uninitialized[y] : &:r0_5 # 208| mu0_6(int) = Uninitialized[y] : &:r0_5
# 209| r0_7(glval<unknown>) = FunctionAddress[memcpy] : # 209| r0_7(glval<unknown>) = FunctionAddress[memcpy] :
# 209| r0_8(glval<int>) = VariableAddress[y] : # 209| r0_8(glval<int>) = VariableAddress[y] :
# 209| r0_9(void *) = Convert : r0_8 # 209| r0_9(void *) = Convert : r0_8
# 209| r0_10(glval<int>) = VariableAddress[x] : # 209| r0_10(glval<int>) = VariableAddress[x] :
# 209| r0_11(void *) = Convert : r0_10 # 209| r0_11(void *) = Convert : r0_10
# 209| r0_12(int) = Constant[4] : # 209| r0_12(int) = Constant[4] :
# 209| r0_13(void *) = Call : func:r0_7, 0:r0_9, 1:r0_11, 2:r0_12 # 209| r0_13(void *) = Call : func:r0_7, 0:r0_9, 1:r0_11, 2:r0_12
# 209| v0_14(void) = ^BufferReadSideEffect : &:r0_11, ~mu0_2 # 209| v0_14(void) = ^SizedBufferReadSideEffect[1] : &:r0_11, r0_12, ~mu0_2
# 209| mu0_15(unknown) = ^BufferMustWriteSideEffect : &:r0_9 # 209| mu0_15(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_9, r0_12
# 210| r0_16(glval<int>) = VariableAddress[#return] : # 210| r0_16(glval<int>) = VariableAddress[#return] :
# 210| r0_17(glval<int>) = VariableAddress[y] : # 210| r0_17(glval<int>) = VariableAddress[y] :
# 210| r0_18(int) = Load : &:r0_17, ~mu0_2 # 210| r0_18(int) = Load : &:r0_17, ~mu0_2
# 210| m0_19(int) = Store : &:r0_16, r0_18 # 210| m0_19(int) = Store : &:r0_16, r0_18
# 207| r0_20(glval<int>) = VariableAddress[#return] : # 207| r0_20(glval<int>) = VariableAddress[#return] :
# 207| v0_21(void) = ReturnValue : &:r0_20, m0_19 # 207| v0_21(void) = ReturnValue : &:r0_20, m0_19
# 207| v0_22(void) = UnmodeledUse : mu* # 207| v0_22(void) = UnmodeledUse : mu*
# 207| v0_23(void) = ExitFunction : # 207| v0_23(void) = ExitFunction :

View File

@@ -71,6 +71,9 @@ private newtype TOpcode =
TBufferReadSideEffect() or TBufferReadSideEffect() or
TBufferMustWriteSideEffect() or TBufferMustWriteSideEffect() or
TBufferMayWriteSideEffect() or TBufferMayWriteSideEffect() or
TSizedBufferReadSideEffect() or
TSizedBufferMustWriteSideEffect() or
TSizedBufferMayWriteSideEffect() or
TChi() or TChi() or
TInlineAsm() or TInlineAsm() or
TUnreached() or TUnreached() or
@@ -147,10 +150,16 @@ abstract class MustWriteSideEffectOpcode extends WriteSideEffectOpcode { }
abstract class MayWriteSideEffectOpcode extends WriteSideEffectOpcode { } abstract class MayWriteSideEffectOpcode extends WriteSideEffectOpcode { }
/** /**
* An opcode that accesses a buffer via an `AddressOperand` and a `BufferSizeOperand`. * An opcode that accesses a buffer via an `AddressOperand`.
*/ */
abstract class BufferAccessOpcode extends MemoryAccessOpcode { } abstract class BufferAccessOpcode extends MemoryAccessOpcode { }
/**
* An opcode that accesses a buffer via an `AddressOperand` with a `BufferSizeOperand` specifying
* the number of elements accessed.
*/
abstract class SizedBufferAccessOpcode extends BufferAccessOpcode { }
module Opcode { module Opcode {
class NoOp extends Opcode, TNoOp { class NoOp extends Opcode, TNoOp {
final override string toString() { result = "NoOp" } final override string toString() { result = "NoOp" }
@@ -445,6 +454,21 @@ module Opcode {
final override string toString() { result = "BufferMayWriteSideEffect" } final override string toString() { result = "BufferMayWriteSideEffect" }
} }
class SizedBufferReadSideEffect extends ReadSideEffectOpcode, SizedBufferAccessOpcode,
TSizedBufferReadSideEffect {
final override string toString() { result = "SizedBufferReadSideEffect" }
}
class SizedBufferMustWriteSideEffect extends MustWriteSideEffectOpcode, SizedBufferAccessOpcode,
TSizedBufferMustWriteSideEffect {
final override string toString() { result = "SizedBufferMustWriteSideEffect" }
}
class SizedBufferMayWriteSideEffect extends MayWriteSideEffectOpcode, SizedBufferAccessOpcode,
TSizedBufferMayWriteSideEffect {
final override string toString() { result = "SizedBufferMayWriteSideEffect" }
}
class Chi extends Opcode, TChi { class Chi extends Opcode, TChi {
final override string toString() { result = "Chi" } final override string toString() { result = "Chi" }
} }

View File

@@ -66,12 +66,14 @@ AddressOperandTag addressOperand() { result = TAddressOperand() }
* The buffer size operand of an instruction that represents a read or write of * The buffer size operand of an instruction that represents a read or write of
* a buffer. * a buffer.
*/ */
class BufferSizeOperand extends RegisterOperandTag, TBufferSizeOperand { class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override string toString() { result = "BufferSize" } final override string toString() { result = "BufferSize" }
final override int getSortOrder() { result = 1 } final override int getSortOrder() { result = 1 }
} }
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
/** /**
* The operand representing the read side effect of a `SideEffectInstruction`. * The operand representing the read side effect of a `SideEffectInstruction`.
*/ */

View File

@@ -30,7 +30,7 @@ module InstructionSanity {
or or
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag
or or
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand opcode instanceof SizedBufferAccessOpcode and tag instanceof BufferSizeOperandTag
or or
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag
or or
@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
final string getValue() { result = value } final string getValue() { result = value }
} }
class IndexedInstruction extends Instruction {
int index;
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
final override string getImmediateString() { result = index.toString() }
final int getIndex() { result = index }
}
class EnterFunctionInstruction extends Instruction { class EnterFunctionInstruction extends Instruction {
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction } EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
} }
@@ -1176,7 +1187,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
class IndirectReadSideEffectInstruction extends SideEffectInstruction { class IndirectReadSideEffectInstruction extends SideEffectInstruction {
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect } IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() } Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
} }
/** /**
@@ -1185,7 +1196,20 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
class BufferReadSideEffectInstruction extends SideEffectInstruction { class BufferReadSideEffectInstruction extends SideEffectInstruction {
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect } BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() } Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
} }
/** /**
@@ -1194,7 +1218,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
class WriteSideEffectInstruction extends SideEffectInstruction { class WriteSideEffectInstruction extends SideEffectInstruction {
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode } WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() } Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
} }
/** /**
@@ -1220,6 +1244,20 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess } final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
} }
/**
* An instruction representing the write of an indirect buffer parameter within a function call. The
* entire buffer is overwritten.
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
}
/** /**
* An instruction representing the potential write of an indirect parameter within a function call. * An instruction representing the potential write of an indirect parameter within a function call.
* Unlike `IndirectWriteSideEffectInstruction`, the location might not be completely overwritten. * Unlike `IndirectWriteSideEffectInstruction`, the location might not be completely overwritten.
@@ -1247,6 +1285,22 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
} }
} }
/**
* An instruction representing the write of an indirect buffer parameter within a function call.
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
final override MemoryAccessKind getResultMemoryAccess() {
result instanceof BufferMayMemoryAccess
}
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
}
/** /**
* An instruction representing a GNU or MSVC inline assembly statement. * An instruction representing a GNU or MSVC inline assembly statement.
*/ */

View File

@@ -254,6 +254,16 @@ class AddressOperand extends RegisterOperand {
override string toString() { result = "Address" } override string toString() { result = "Address" }
} }
/**
* The buffer size operand of an instruction that represents a read or write of
* a buffer.
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/** /**
* The source value operand of an instruction that loads a value from memory (e.g. `Load`, * The source value operand of an instruction that loads a value from memory (e.g. `Load`,
* `ReturnValue`, `ThrowValue`). * `ReturnValue`, `ThrowValue`).