Merge pull request #3481 from dbartol/github/codeql-c-analysis-team/69

C++/C#: Allow memory operands to lack a definition
This commit is contained in:
Mathias Vorreiter Pedersen
2020-05-16 11:53:00 +02:00
committed by GitHub
9 changed files with 429 additions and 266 deletions

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -221,7 +221,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
result = TPositionalArgumentOperand(argIndex)
}
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
abstract class ChiOperandTag extends MemoryOperandTag { }
class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override string toString() { result = "ChiTotal" }
final override int getSortOrder() { result = 13 }
@@ -231,7 +233,7 @@ class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override string toString() { result = "ChiPartial" }
final override int getSortOrder() { result = 14 }

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -1,7 +1,6 @@
missingOperand
unexpectedOperand
duplicateOperand
| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
missingPhiOperand
missingOperandType
duplicateChiOperand

View File

@@ -1480,7 +1480,7 @@ ssa.cpp:
# 304| r304_5(char) = Load : &:r304_4, ~m303_8
# 304| r304_6(int) = Convert : r304_5
# 304| m304_7(int) = Store : &:r304_1, r304_6
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11, m303_11
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, m303_11
# 301| r301_13(glval<int>) = VariableAddress[#return] :
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
# 301| v301_15(void) = AliasedUse : ~m303_8

View File

@@ -221,7 +221,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
result = TPositionalArgumentOperand(argIndex)
}
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
abstract class ChiOperandTag extends MemoryOperandTag { }
class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override string toString() { result = "ChiTotal" }
final override int getSortOrder() { result = 13 }
@@ -231,7 +233,7 @@ class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override string toString() { result = "ChiPartial" }
final override int getSortOrder() { result = 14 }

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}