C++: Sync Opcode.qll QLDoc with Instruction.qll QLDoc

For every concrete `Opcode`, there is a corresponding `Instruction` class. Rather than duplicate all of the QLDoc by hand, I wrote a quick Python script to copy the QLDoc from `Instruction.qll` to `Opcode.qll`. I don't expect that we will need to do this often, so I'm not hooking it up to a PR check or anything like that, but I did commit the script itself in case we need it again.
This commit is contained in:
Dave Bartolomeo
2020-06-26 11:42:32 -04:00
parent 023e1dc0a2
commit 281985b845
3 changed files with 629 additions and 0 deletions

83
config/opcode-qldoc.py Normal file
View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python3
import os
import re
path = os.path
start_qldoc_re = re.compile(r'^\s*/\*\*') # Start of a QLDoc comment
end_qldoc_re = re.compile(r'\*/\s*$') # End of a QLDoc comment
blank_qldoc_line_re = re.compile(r'^\s*\*\s*$') # A line in a QLDoc comment with only the '*'
instruction_class_re = re.compile(r'^class (?P<name>[A-aa-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
opcode_class_re = re.compile(r'^\s*class (?P<name>[A-aa-z0-9]+)\s') # Declaration of an `Opcode` class
script_dir = path.realpath(path.dirname(__file__))
instruction_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll'))
opcode_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll'))
# Scan `Instruction.qll`, keeping track of the QLDoc comment attached to each declaration of a class
# whose name ends with `Instruction`.
instruction_comments = {}
in_qldoc = False
saw_blank_line_in_qldoc = False
qldoc_lines = []
with open(instruction_path, 'r', encoding='utf-8') as instr:
for line in instr:
if in_qldoc:
if end_qldoc_re.search(line):
qldoc_lines.append(line)
in_qldoc = False
elif blank_qldoc_line_re.search(line):
# We're going to skip any lines after the first blank line, to avoid duplicating all
# of the verbose description.
saw_blank_line_in_qldoc = True
elif not saw_blank_line_in_qldoc:
qldoc_lines.append(line)
else:
if start_qldoc_re.search(line):
# Starting a new QLDoc comment.
saw_blank_line_in_qldoc = False
qldoc_lines.append(line)
if not end_qldoc_re.search(line):
in_qldoc = True
else:
instruction_match = instruction_class_re.search(line)
if instruction_match:
# Found the declaration of an `Instruction` class. Record the QLDoc comments.
instruction_comments[instruction_match.group('name')] = qldoc_lines
qldoc_lines = []
# Scan `Opcode.qll`. Whenever we see the declaration of an `Opcode` class for which we have a
# corresponding `Instruction` class, we'll attach a copy of the `Instruction`'s QLDoc comment.
in_qldoc = False
qldoc_lines = []
output_lines = []
with open(opcode_path, 'r', encoding='utf-8') as opcode:
for line in opcode:
if in_qldoc:
qldoc_lines.append(line)
if end_qldoc_re.search(line):
in_qldoc = False
else:
if start_qldoc_re.search(line):
qldoc_lines.append(line)
if not end_qldoc_re.search(line):
in_qldoc = True
else:
opcode_match = opcode_class_re.search(line)
if opcode_match:
# Found an `Opcode` that matches a known `Instruction`. Replace the QLDoc with
# a copy of the one from the `Instruction`.
name = opcode_match.group('name')
if instruction_comments.get(name):
# Indent by two additional spaces, since opcodes are declared in the
# `Opcode` module.
# Rename `instruction` to `operation`.
qldoc_lines = [(' ' + qldoc_line.replace(' An instruction ', ' An operation '))
for qldoc_line in instruction_comments[name]]
output_lines.extend(qldoc_lines)
qldoc_lines = []
output_lines.append(line)
# Write out the updated `Opcode.qll`
with open(opcode_path, 'w', encoding='utf-8') as opcode:
opcode.writelines(output_lines)

View File

@@ -338,46 +338,84 @@ abstract class WriteSideEffectOpcode extends SideEffectOpcode { }
* Provides `Opcode`s that specify the operation performed by an `Instruction`.
*/
module Opcode {
/**
* An operation that has no effect.
*/
class NoOp extends Opcode, TNoOp {
final override string toString() { result = "NoOp" }
}
/**
* An operation that returns an uninitialized value.
*/
class Uninitialized extends IndirectWriteOpcode, TUninitialized {
final override string toString() { result = "Uninitialized" }
}
/**
* An operation that produces a well-defined but unknown result and has
* unknown side effects, including side effects that are not conservatively
* modeled in the SSA graph.
*/
class Error extends Opcode, TError {
final override string toString() { result = "Error" }
}
/**
* An operation that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
*/
class InitializeParameter extends IndirectWriteOpcode, TInitializeParameter {
final override string toString() { result = "InitializeParameter" }
}
/**
* An operation that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.
*/
class InitializeIndirection extends EntireAllocationWriteOpcode, TInitializeIndirection {
final override string toString() { result = "InitializeIndirection" }
}
/**
* An operation that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThis extends Opcode, TInitializeThis {
final override string toString() { result = "InitializeThis" }
}
/**
* An operation representing the entry point to a function.
*/
class EnterFunction extends Opcode, TEnterFunction {
final override string toString() { result = "EnterFunction" }
}
/**
* An operation representing the exit point of a function.
*/
class ExitFunction extends Opcode, TExitFunction {
final override string toString() { result = "ExitFunction" }
}
/**
* An operation that returns control to the caller of the function, including a return value.
*/
class ReturnValue extends ReturnOpcode, OpcodeWithLoad, TReturnValue {
final override string toString() { result = "ReturnValue" }
}
/**
* An operation that returns control to the caller of the function, without returning a value.
*/
class ReturnVoid extends ReturnOpcode, TReturnVoid {
final override string toString() { result = "ReturnVoid" }
}
/**
* An operation that represents the use of the value pointed to by a parameter of the function
* after the function returns control to its caller.
*/
class ReturnIndirection extends EntireAllocationReadOpcode, TReturnIndirection {
final override string toString() { result = "ReturnIndirection" }
@@ -386,14 +424,23 @@ module Opcode {
}
}
/**
* An operation that returns a register result containing a copy of its register operand.
*/
class CopyValue extends UnaryOpcode, CopyOpcode, TCopyValue {
final override string toString() { result = "CopyValue" }
}
/**
* An operation that returns a register result containing a copy of its memory operand.
*/
class Load extends CopyOpcode, OpcodeWithLoad, TLoad {
final override string toString() { result = "Load" }
}
/**
* An operation that returns a memory result containing a copy of its register operand.
*/
class Store extends CopyOpcode, IndirectWriteOpcode, TStore {
final override string toString() { result = "Store" }
@@ -402,154 +449,282 @@ module Opcode {
}
}
/**
* An operation that computes the sum of two numeric operands.
*/
class Add extends BinaryArithmeticOpcode, TAdd {
final override string toString() { result = "Add" }
}
/**
* An operation that computes the difference of two numeric operands.
*/
class Sub extends BinaryArithmeticOpcode, TSub {
final override string toString() { result = "Sub" }
}
/**
* An operation that computes the product of two numeric operands.
*/
class Mul extends BinaryArithmeticOpcode, TMul {
final override string toString() { result = "Mul" }
}
/**
* An operation that computes the quotient of two numeric operands.
*/
class Div extends BinaryArithmeticOpcode, TDiv {
final override string toString() { result = "Div" }
}
/**
* An operation that computes the remainder of two integer operands.
*/
class Rem extends BinaryArithmeticOpcode, TRem {
final override string toString() { result = "Rem" }
}
/**
* An operation that negates a single numeric operand.
*/
class Negate extends UnaryArithmeticOpcode, TNegate {
final override string toString() { result = "Negate" }
}
/**
* An operation that shifts its left operand to the left by the number of bits specified by its
* right operand.
*/
class ShiftLeft extends BinaryBitwiseOpcode, TShiftLeft {
final override string toString() { result = "ShiftLeft" }
}
/**
* An operation that shifts its left operand to the right by the number of bits specified by its
* right operand.
*/
class ShiftRight extends BinaryBitwiseOpcode, TShiftRight {
final override string toString() { result = "ShiftRight" }
}
/**
* An operation that computes the bitwise "and" of two integer operands.
*/
class BitAnd extends BinaryBitwiseOpcode, TBitAnd {
final override string toString() { result = "BitAnd" }
}
/**
* An operation that computes the bitwise "or" of two integer operands.
*/
class BitOr extends BinaryBitwiseOpcode, TBitOr {
final override string toString() { result = "BitOr" }
}
/**
* An operation that computes the bitwise "xor" of two integer operands.
*/
class BitXor extends BinaryBitwiseOpcode, TBitXor {
final override string toString() { result = "BitXor" }
}
/**
* An operation that computes the bitwise complement of its operand.
*/
class BitComplement extends UnaryBitwiseOpcode, TBitComplement {
final override string toString() { result = "BitComplement" }
}
/**
* An operation that computes the logical complement of its operand.
*/
class LogicalNot extends UnaryOpcode, TLogicalNot {
final override string toString() { result = "LogicalNot" }
}
/**
* An operation that returns a `true` result if its operands are equal.
*/
class CompareEQ extends CompareOpcode, TCompareEQ {
final override string toString() { result = "CompareEQ" }
}
/**
* An operation that returns a `true` result if its operands are not equal.
*/
class CompareNE extends CompareOpcode, TCompareNE {
final override string toString() { result = "CompareNE" }
}
/**
* An operation that returns a `true` result if its left operand is less than its right operand.
*/
class CompareLT extends RelationalOpcode, TCompareLT {
final override string toString() { result = "CompareLT" }
}
/**
* An operation that returns a `true` result if its left operand is greater than its right operand.
*/
class CompareGT extends RelationalOpcode, TCompareGT {
final override string toString() { result = "CompareGT" }
}
/**
* An operation that returns a `true` result if its left operand is less than or equal to its
* right operand.
*/
class CompareLE extends RelationalOpcode, TCompareLE {
final override string toString() { result = "CompareLE" }
}
/**
* An operation that returns a `true` result if its left operand is greater than or equal to its
* right operand.
*/
class CompareGE extends RelationalOpcode, TCompareGE {
final override string toString() { result = "CompareGE" }
}
/**
* An operation that adds an integer offset to a pointer.
*/
class PointerAdd extends PointerOffsetOpcode, TPointerAdd {
final override string toString() { result = "PointerAdd" }
}
/**
* An operation that subtracts an integer offset from a pointer.
*/
class PointerSub extends PointerOffsetOpcode, TPointerSub {
final override string toString() { result = "PointerSub" }
}
/**
* An operation that computes the difference between two pointers.
*/
class PointerDiff extends PointerArithmeticOpcode, TPointerDiff {
final override string toString() { result = "PointerDiff" }
}
/**
* An operation that converts the value of its operand to a value of a different type.
*/
class Convert extends UnaryOpcode, TConvert {
final override string toString() { result = "Convert" }
}
/**
* An operation that converts from the address of a derived class to the address of a direct
* non-virtual base class.
*/
class ConvertToNonVirtualBase extends ConvertToBaseOpcode, TConvertToNonVirtualBase {
final override string toString() { result = "ConvertToNonVirtualBase" }
}
/**
* An operation that converts from the address of a derived class to the address of a virtual base
* class.
*/
class ConvertToVirtualBase extends ConvertToBaseOpcode, TConvertToVirtualBase {
final override string toString() { result = "ConvertToVirtualBase" }
}
/**
* An operation that converts from the address of a base class to the address of a direct
* non-virtual derived class.
*/
class ConvertToDerived extends UnaryOpcode, TConvertToDerived {
final override string toString() { result = "ConvertToDerived" }
}
/**
* An operation that converts the address of a polymorphic object to the address of a different
* subobject of the same polymorphic object, returning a null address if the dynamic type of the
* object is not compatible with the result type.
*/
class CheckedConvertOrNull extends UnaryOpcode, TCheckedConvertOrNull {
final override string toString() { result = "CheckedConvertOrNull" }
}
/**
* An operation that converts the address of a polymorphic object to the address of a different
* subobject of the same polymorphic object, throwing an exception if the dynamic type of the object
* is not compatible with the result type.
*/
class CheckedConvertOrThrow extends UnaryOpcode, TCheckedConvertOrThrow {
final override string toString() { result = "CheckedConvertOrThrow" }
}
/**
* An operation that returns the address of the complete object that contains the subobject
* pointed to by its operand.
*/
class CompleteObjectAddress extends UnaryOpcode, TCompleteObjectAddress {
final override string toString() { result = "CompleteObjectAddress" }
}
/**
* An operation that returns the address of a variable.
*/
class VariableAddress extends Opcode, TVariableAddress {
final override string toString() { result = "VariableAddress" }
}
/**
* An operation that computes the address of a non-static field of an object.
*/
class FieldAddress extends UnaryOpcode, TFieldAddress {
final override string toString() { result = "FieldAddress" }
}
/**
* An operation that computes the address of the first element of a managed array.
*/
class ElementsAddress extends UnaryOpcode, TElementsAddress {
final override string toString() { result = "ElementsAddress" }
}
/**
* An operation that returns the address of a function.
*/
class FunctionAddress extends Opcode, TFunctionAddress {
final override string toString() { result = "FunctionAddress" }
}
/**
* An operation whose result is a constant value.
*/
class Constant extends Opcode, TConstant {
final override string toString() { result = "Constant" }
}
/**
* An operation whose result is the address of a string literal.
*/
class StringConstant extends Opcode, TStringConstant {
final override string toString() { result = "StringConstant" }
}
/**
* An operation that branches to one of two successor instructions based on the value of a Boolean
* operand.
*/
class ConditionalBranch extends OpcodeWithCondition, TConditionalBranch {
final override string toString() { result = "ConditionalBranch" }
}
/**
* An operation that branches to one of multiple successor instructions based on the value of an
* integer operand.
*/
class Switch extends OpcodeWithCondition, TSwitch {
final override string toString() { result = "Switch" }
}
/**
* An operation that calls a function.
*/
class Call extends Opcode, TCall {
final override string toString() { result = "Call" }
@@ -558,32 +733,53 @@ module Opcode {
}
}
/**
* An operation that catches an exception of a specific type.
*/
class CatchByType extends CatchOpcode, TCatchByType {
final override string toString() { result = "CatchByType" }
}
/**
* An operation that catches any exception.
*/
class CatchAny extends CatchOpcode, TCatchAny {
final override string toString() { result = "CatchAny" }
}
/**
* An operation that throws a new exception.
*/
class ThrowValue extends ThrowOpcode, OpcodeWithLoad, TThrowValue {
final override string toString() { result = "ThrowValue" }
}
/**
* An operation that re-throws the current exception.
*/
class ReThrow extends ThrowOpcode, TReThrow {
final override string toString() { result = "ReThrow" }
}
/**
* An operation that exits the current function by propagating an exception.
*/
class Unwind extends Opcode, TUnwind {
final override string toString() { result = "Unwind" }
}
/**
* An operation that initializes all escaped memory.
*/
class AliasedDefinition extends Opcode, TAliasedDefinition {
final override string toString() { result = "AliasedDefinition" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An operation that initializes all memory that existed before this function was called.
*/
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
final override string toString() { result = "InitializeNonLocal" }
@@ -592,6 +788,9 @@ module Opcode {
}
}
/**
* An operation that consumes all escaped memory on exit from the function.
*/
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
@@ -602,92 +801,157 @@ module Opcode {
}
}
/**
* An operation representing the choice of one of multiple input values based on control flow.
*/
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof PhiMemoryAccess }
}
/**
* An operation representing a built-in operation that does not have a specific opcode. The
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltIn extends BuiltInOperationOpcode, TBuiltIn {
final override string toString() { result = "BuiltIn" }
}
/**
* An operation that returns a `va_list` to access the arguments passed to the `...` parameter.
*/
class VarArgsStart extends UnaryOpcode, TVarArgsStart {
final override string toString() { result = "VarArgsStart" }
}
/**
* An operation that cleans up a `va_list` after it is no longer in use.
*/
class VarArgsEnd extends UnaryOpcode, TVarArgsEnd {
final override string toString() { result = "VarArgsEnd" }
}
/**
* An operation that returns the address of the argument currently pointed to by a `va_list`.
*/
class VarArg extends UnaryOpcode, TVarArg {
final override string toString() { result = "VarArg" }
}
/**
* An operation that modifies a `va_list` to point to the next argument that was passed to the
* `...` parameter.
*/
class NextVarArg extends UnaryOpcode, TNextVarArg {
final override string toString() { result = "NextVarArg" }
}
/**
* An operation representing the side effect of a function call on any memory that might be
* accessed by that call.
*/
class CallSideEffect extends WriteSideEffectOpcode, EscapedWriteOpcode, MayWriteOpcode,
ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode, TCallSideEffect {
final override string toString() { result = "CallSideEffect" }
}
/**
* An operation representing the side effect of a function call on any memory
* that might be read by that call.
*/
class CallReadSideEffect extends ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode,
TCallReadSideEffect {
final override string toString() { result = "CallReadSideEffect" }
}
/**
* An operation representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffect extends ReadSideEffectOpcode, IndirectReadOpcode,
TIndirectReadSideEffect {
final override string toString() { result = "IndirectReadSideEffect" }
}
/**
* An operation representing the write of an indirect parameter within a function call.
*/
class IndirectMustWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
TIndirectMustWriteSideEffect {
final override string toString() { result = "IndirectMustWriteSideEffect" }
}
/**
* An operation representing the potential write of an indirect parameter within a function call.
*/
class IndirectMayWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
MayWriteOpcode, TIndirectMayWriteSideEffect {
final override string toString() { result = "IndirectMayWriteSideEffect" }
}
/**
* An operation representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffect extends ReadSideEffectOpcode, UnsizedBufferReadOpcode,
TBufferReadSideEffect {
final override string toString() { result = "BufferReadSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call. The
* entire buffer is overwritten.
*/
class BufferMustWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
TBufferMustWriteSideEffect {
final override string toString() { result = "BufferMustWriteSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call.
*/
class BufferMayWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
MayWriteOpcode, TBufferMayWriteSideEffect {
final override string toString() { result = "BufferMayWriteSideEffect" }
}
/**
* An operation representing the read of an indirect buffer parameter within a function call.
*/
class SizedBufferReadSideEffect extends ReadSideEffectOpcode, SizedBufferReadOpcode,
TSizedBufferReadSideEffect {
final override string toString() { result = "SizedBufferReadSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call. The
* entire buffer is overwritten.
*/
class SizedBufferMustWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
TSizedBufferMustWriteSideEffect {
final override string toString() { result = "SizedBufferMustWriteSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call.
*/
class SizedBufferMayWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
MayWriteOpcode, TSizedBufferMayWriteSideEffect {
final override string toString() { result = "SizedBufferMayWriteSideEffect" }
}
/**
* An operation representing the initial value of newly allocated memory, such as the result of a
* call to `malloc`.
*/
class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode,
TInitializeDynamicAllocation {
final override string toString() { result = "InitializeDynamicAllocation" }
}
/**
* An operation representing the effect that a write to a memory may have on potential aliases of
* that memory.
*/
class Chi extends Opcode, TChi {
final override string toString() { result = "Chi" }
@@ -702,6 +966,9 @@ module Opcode {
}
}
/**
* An operation representing a GNU or MSVC inline assembly statement.
*/
class InlineAsm extends Opcode, EscapedWriteOpcode, MayWriteOpcode, EscapedReadOpcode,
MayReadOpcode, TInlineAsm {
final override string toString() { result = "InlineAsm" }
@@ -711,10 +978,16 @@ module Opcode {
}
}
/**
* An operation representing unreachable code.
*/
class Unreached extends Opcode, TUnreached {
final override string toString() { result = "Unreached" }
}
/**
* An operation that allocates a new object on the managed heap.
*/
class NewObj extends Opcode, TNewObj {
final override string toString() { result = "NewObj" }
}

View File

@@ -338,46 +338,84 @@ abstract class WriteSideEffectOpcode extends SideEffectOpcode { }
* Provides `Opcode`s that specify the operation performed by an `Instruction`.
*/
module Opcode {
/**
* An operation that has no effect.
*/
class NoOp extends Opcode, TNoOp {
final override string toString() { result = "NoOp" }
}
/**
* An operation that returns an uninitialized value.
*/
class Uninitialized extends IndirectWriteOpcode, TUninitialized {
final override string toString() { result = "Uninitialized" }
}
/**
* An operation that produces a well-defined but unknown result and has
* unknown side effects, including side effects that are not conservatively
* modeled in the SSA graph.
*/
class Error extends Opcode, TError {
final override string toString() { result = "Error" }
}
/**
* An operation that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
*/
class InitializeParameter extends IndirectWriteOpcode, TInitializeParameter {
final override string toString() { result = "InitializeParameter" }
}
/**
* An operation that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.
*/
class InitializeIndirection extends EntireAllocationWriteOpcode, TInitializeIndirection {
final override string toString() { result = "InitializeIndirection" }
}
/**
* An operation that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThis extends Opcode, TInitializeThis {
final override string toString() { result = "InitializeThis" }
}
/**
* An operation representing the entry point to a function.
*/
class EnterFunction extends Opcode, TEnterFunction {
final override string toString() { result = "EnterFunction" }
}
/**
* An operation representing the exit point of a function.
*/
class ExitFunction extends Opcode, TExitFunction {
final override string toString() { result = "ExitFunction" }
}
/**
* An operation that returns control to the caller of the function, including a return value.
*/
class ReturnValue extends ReturnOpcode, OpcodeWithLoad, TReturnValue {
final override string toString() { result = "ReturnValue" }
}
/**
* An operation that returns control to the caller of the function, without returning a value.
*/
class ReturnVoid extends ReturnOpcode, TReturnVoid {
final override string toString() { result = "ReturnVoid" }
}
/**
* An operation that represents the use of the value pointed to by a parameter of the function
* after the function returns control to its caller.
*/
class ReturnIndirection extends EntireAllocationReadOpcode, TReturnIndirection {
final override string toString() { result = "ReturnIndirection" }
@@ -386,14 +424,23 @@ module Opcode {
}
}
/**
* An operation that returns a register result containing a copy of its register operand.
*/
class CopyValue extends UnaryOpcode, CopyOpcode, TCopyValue {
final override string toString() { result = "CopyValue" }
}
/**
* An operation that returns a register result containing a copy of its memory operand.
*/
class Load extends CopyOpcode, OpcodeWithLoad, TLoad {
final override string toString() { result = "Load" }
}
/**
* An operation that returns a memory result containing a copy of its register operand.
*/
class Store extends CopyOpcode, IndirectWriteOpcode, TStore {
final override string toString() { result = "Store" }
@@ -402,154 +449,282 @@ module Opcode {
}
}
/**
* An operation that computes the sum of two numeric operands.
*/
class Add extends BinaryArithmeticOpcode, TAdd {
final override string toString() { result = "Add" }
}
/**
* An operation that computes the difference of two numeric operands.
*/
class Sub extends BinaryArithmeticOpcode, TSub {
final override string toString() { result = "Sub" }
}
/**
* An operation that computes the product of two numeric operands.
*/
class Mul extends BinaryArithmeticOpcode, TMul {
final override string toString() { result = "Mul" }
}
/**
* An operation that computes the quotient of two numeric operands.
*/
class Div extends BinaryArithmeticOpcode, TDiv {
final override string toString() { result = "Div" }
}
/**
* An operation that computes the remainder of two integer operands.
*/
class Rem extends BinaryArithmeticOpcode, TRem {
final override string toString() { result = "Rem" }
}
/**
* An operation that negates a single numeric operand.
*/
class Negate extends UnaryArithmeticOpcode, TNegate {
final override string toString() { result = "Negate" }
}
/**
* An operation that shifts its left operand to the left by the number of bits specified by its
* right operand.
*/
class ShiftLeft extends BinaryBitwiseOpcode, TShiftLeft {
final override string toString() { result = "ShiftLeft" }
}
/**
* An operation that shifts its left operand to the right by the number of bits specified by its
* right operand.
*/
class ShiftRight extends BinaryBitwiseOpcode, TShiftRight {
final override string toString() { result = "ShiftRight" }
}
/**
* An operation that computes the bitwise "and" of two integer operands.
*/
class BitAnd extends BinaryBitwiseOpcode, TBitAnd {
final override string toString() { result = "BitAnd" }
}
/**
* An operation that computes the bitwise "or" of two integer operands.
*/
class BitOr extends BinaryBitwiseOpcode, TBitOr {
final override string toString() { result = "BitOr" }
}
/**
* An operation that computes the bitwise "xor" of two integer operands.
*/
class BitXor extends BinaryBitwiseOpcode, TBitXor {
final override string toString() { result = "BitXor" }
}
/**
* An operation that computes the bitwise complement of its operand.
*/
class BitComplement extends UnaryBitwiseOpcode, TBitComplement {
final override string toString() { result = "BitComplement" }
}
/**
* An operation that computes the logical complement of its operand.
*/
class LogicalNot extends UnaryOpcode, TLogicalNot {
final override string toString() { result = "LogicalNot" }
}
/**
* An operation that returns a `true` result if its operands are equal.
*/
class CompareEQ extends CompareOpcode, TCompareEQ {
final override string toString() { result = "CompareEQ" }
}
/**
* An operation that returns a `true` result if its operands are not equal.
*/
class CompareNE extends CompareOpcode, TCompareNE {
final override string toString() { result = "CompareNE" }
}
/**
* An operation that returns a `true` result if its left operand is less than its right operand.
*/
class CompareLT extends RelationalOpcode, TCompareLT {
final override string toString() { result = "CompareLT" }
}
/**
* An operation that returns a `true` result if its left operand is greater than its right operand.
*/
class CompareGT extends RelationalOpcode, TCompareGT {
final override string toString() { result = "CompareGT" }
}
/**
* An operation that returns a `true` result if its left operand is less than or equal to its
* right operand.
*/
class CompareLE extends RelationalOpcode, TCompareLE {
final override string toString() { result = "CompareLE" }
}
/**
* An operation that returns a `true` result if its left operand is greater than or equal to its
* right operand.
*/
class CompareGE extends RelationalOpcode, TCompareGE {
final override string toString() { result = "CompareGE" }
}
/**
* An operation that adds an integer offset to a pointer.
*/
class PointerAdd extends PointerOffsetOpcode, TPointerAdd {
final override string toString() { result = "PointerAdd" }
}
/**
* An operation that subtracts an integer offset from a pointer.
*/
class PointerSub extends PointerOffsetOpcode, TPointerSub {
final override string toString() { result = "PointerSub" }
}
/**
* An operation that computes the difference between two pointers.
*/
class PointerDiff extends PointerArithmeticOpcode, TPointerDiff {
final override string toString() { result = "PointerDiff" }
}
/**
* An operation that converts the value of its operand to a value of a different type.
*/
class Convert extends UnaryOpcode, TConvert {
final override string toString() { result = "Convert" }
}
/**
* An operation that converts from the address of a derived class to the address of a direct
* non-virtual base class.
*/
class ConvertToNonVirtualBase extends ConvertToBaseOpcode, TConvertToNonVirtualBase {
final override string toString() { result = "ConvertToNonVirtualBase" }
}
/**
* An operation that converts from the address of a derived class to the address of a virtual base
* class.
*/
class ConvertToVirtualBase extends ConvertToBaseOpcode, TConvertToVirtualBase {
final override string toString() { result = "ConvertToVirtualBase" }
}
/**
* An operation that converts from the address of a base class to the address of a direct
* non-virtual derived class.
*/
class ConvertToDerived extends UnaryOpcode, TConvertToDerived {
final override string toString() { result = "ConvertToDerived" }
}
/**
* An operation that converts the address of a polymorphic object to the address of a different
* subobject of the same polymorphic object, returning a null address if the dynamic type of the
* object is not compatible with the result type.
*/
class CheckedConvertOrNull extends UnaryOpcode, TCheckedConvertOrNull {
final override string toString() { result = "CheckedConvertOrNull" }
}
/**
* An operation that converts the address of a polymorphic object to the address of a different
* subobject of the same polymorphic object, throwing an exception if the dynamic type of the object
* is not compatible with the result type.
*/
class CheckedConvertOrThrow extends UnaryOpcode, TCheckedConvertOrThrow {
final override string toString() { result = "CheckedConvertOrThrow" }
}
/**
* An operation that returns the address of the complete object that contains the subobject
* pointed to by its operand.
*/
class CompleteObjectAddress extends UnaryOpcode, TCompleteObjectAddress {
final override string toString() { result = "CompleteObjectAddress" }
}
/**
* An operation that returns the address of a variable.
*/
class VariableAddress extends Opcode, TVariableAddress {
final override string toString() { result = "VariableAddress" }
}
/**
* An operation that computes the address of a non-static field of an object.
*/
class FieldAddress extends UnaryOpcode, TFieldAddress {
final override string toString() { result = "FieldAddress" }
}
/**
* An operation that computes the address of the first element of a managed array.
*/
class ElementsAddress extends UnaryOpcode, TElementsAddress {
final override string toString() { result = "ElementsAddress" }
}
/**
* An operation that returns the address of a function.
*/
class FunctionAddress extends Opcode, TFunctionAddress {
final override string toString() { result = "FunctionAddress" }
}
/**
* An operation whose result is a constant value.
*/
class Constant extends Opcode, TConstant {
final override string toString() { result = "Constant" }
}
/**
* An operation whose result is the address of a string literal.
*/
class StringConstant extends Opcode, TStringConstant {
final override string toString() { result = "StringConstant" }
}
/**
* An operation that branches to one of two successor instructions based on the value of a Boolean
* operand.
*/
class ConditionalBranch extends OpcodeWithCondition, TConditionalBranch {
final override string toString() { result = "ConditionalBranch" }
}
/**
* An operation that branches to one of multiple successor instructions based on the value of an
* integer operand.
*/
class Switch extends OpcodeWithCondition, TSwitch {
final override string toString() { result = "Switch" }
}
/**
* An operation that calls a function.
*/
class Call extends Opcode, TCall {
final override string toString() { result = "Call" }
@@ -558,32 +733,53 @@ module Opcode {
}
}
/**
* An operation that catches an exception of a specific type.
*/
class CatchByType extends CatchOpcode, TCatchByType {
final override string toString() { result = "CatchByType" }
}
/**
* An operation that catches any exception.
*/
class CatchAny extends CatchOpcode, TCatchAny {
final override string toString() { result = "CatchAny" }
}
/**
* An operation that throws a new exception.
*/
class ThrowValue extends ThrowOpcode, OpcodeWithLoad, TThrowValue {
final override string toString() { result = "ThrowValue" }
}
/**
* An operation that re-throws the current exception.
*/
class ReThrow extends ThrowOpcode, TReThrow {
final override string toString() { result = "ReThrow" }
}
/**
* An operation that exits the current function by propagating an exception.
*/
class Unwind extends Opcode, TUnwind {
final override string toString() { result = "Unwind" }
}
/**
* An operation that initializes all escaped memory.
*/
class AliasedDefinition extends Opcode, TAliasedDefinition {
final override string toString() { result = "AliasedDefinition" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An operation that initializes all memory that existed before this function was called.
*/
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
final override string toString() { result = "InitializeNonLocal" }
@@ -592,6 +788,9 @@ module Opcode {
}
}
/**
* An operation that consumes all escaped memory on exit from the function.
*/
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
@@ -602,92 +801,157 @@ module Opcode {
}
}
/**
* An operation representing the choice of one of multiple input values based on control flow.
*/
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof PhiMemoryAccess }
}
/**
* An operation representing a built-in operation that does not have a specific opcode. The
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltIn extends BuiltInOperationOpcode, TBuiltIn {
final override string toString() { result = "BuiltIn" }
}
/**
* An operation that returns a `va_list` to access the arguments passed to the `...` parameter.
*/
class VarArgsStart extends UnaryOpcode, TVarArgsStart {
final override string toString() { result = "VarArgsStart" }
}
/**
* An operation that cleans up a `va_list` after it is no longer in use.
*/
class VarArgsEnd extends UnaryOpcode, TVarArgsEnd {
final override string toString() { result = "VarArgsEnd" }
}
/**
* An operation that returns the address of the argument currently pointed to by a `va_list`.
*/
class VarArg extends UnaryOpcode, TVarArg {
final override string toString() { result = "VarArg" }
}
/**
* An operation that modifies a `va_list` to point to the next argument that was passed to the
* `...` parameter.
*/
class NextVarArg extends UnaryOpcode, TNextVarArg {
final override string toString() { result = "NextVarArg" }
}
/**
* An operation representing the side effect of a function call on any memory that might be
* accessed by that call.
*/
class CallSideEffect extends WriteSideEffectOpcode, EscapedWriteOpcode, MayWriteOpcode,
ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode, TCallSideEffect {
final override string toString() { result = "CallSideEffect" }
}
/**
* An operation representing the side effect of a function call on any memory
* that might be read by that call.
*/
class CallReadSideEffect extends ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode,
TCallReadSideEffect {
final override string toString() { result = "CallReadSideEffect" }
}
/**
* An operation representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffect extends ReadSideEffectOpcode, IndirectReadOpcode,
TIndirectReadSideEffect {
final override string toString() { result = "IndirectReadSideEffect" }
}
/**
* An operation representing the write of an indirect parameter within a function call.
*/
class IndirectMustWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
TIndirectMustWriteSideEffect {
final override string toString() { result = "IndirectMustWriteSideEffect" }
}
/**
* An operation representing the potential write of an indirect parameter within a function call.
*/
class IndirectMayWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
MayWriteOpcode, TIndirectMayWriteSideEffect {
final override string toString() { result = "IndirectMayWriteSideEffect" }
}
/**
* An operation representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffect extends ReadSideEffectOpcode, UnsizedBufferReadOpcode,
TBufferReadSideEffect {
final override string toString() { result = "BufferReadSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call. The
* entire buffer is overwritten.
*/
class BufferMustWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
TBufferMustWriteSideEffect {
final override string toString() { result = "BufferMustWriteSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call.
*/
class BufferMayWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
MayWriteOpcode, TBufferMayWriteSideEffect {
final override string toString() { result = "BufferMayWriteSideEffect" }
}
/**
* An operation representing the read of an indirect buffer parameter within a function call.
*/
class SizedBufferReadSideEffect extends ReadSideEffectOpcode, SizedBufferReadOpcode,
TSizedBufferReadSideEffect {
final override string toString() { result = "SizedBufferReadSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call. The
* entire buffer is overwritten.
*/
class SizedBufferMustWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
TSizedBufferMustWriteSideEffect {
final override string toString() { result = "SizedBufferMustWriteSideEffect" }
}
/**
* An operation representing the write of an indirect buffer parameter within a function call.
*/
class SizedBufferMayWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
MayWriteOpcode, TSizedBufferMayWriteSideEffect {
final override string toString() { result = "SizedBufferMayWriteSideEffect" }
}
/**
* An operation representing the initial value of newly allocated memory, such as the result of a
* call to `malloc`.
*/
class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode,
TInitializeDynamicAllocation {
final override string toString() { result = "InitializeDynamicAllocation" }
}
/**
* An operation representing the effect that a write to a memory may have on potential aliases of
* that memory.
*/
class Chi extends Opcode, TChi {
final override string toString() { result = "Chi" }
@@ -702,6 +966,9 @@ module Opcode {
}
}
/**
* An operation representing a GNU or MSVC inline assembly statement.
*/
class InlineAsm extends Opcode, EscapedWriteOpcode, MayWriteOpcode, EscapedReadOpcode,
MayReadOpcode, TInlineAsm {
final override string toString() { result = "InlineAsm" }
@@ -711,10 +978,16 @@ module Opcode {
}
}
/**
* An operation representing unreachable code.
*/
class Unreached extends Opcode, TUnreached {
final override string toString() { result = "Unreached" }
}
/**
* An operation that allocates a new object on the managed heap.
*/
class NewObj extends Opcode, TNewObj {
final override string toString() { result = "NewObj" }
}