From edf5da448176eabce5d98b099e1d20e4ec0bf324 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 9 Oct 2018 13:07:33 +0200 Subject: [PATCH] C#: Move cached CIL predicates into same stage --- csharp/ql/src/semmle/code/cil/Access.qll | 1 - csharp/ql/src/semmle/code/cil/ControlFlow.qll | 417 ++++++++++++++++-- csharp/ql/src/semmle/code/cil/Handler.qll | 6 - csharp/ql/src/semmle/code/cil/Instruction.qll | 9 - .../src/semmle/code/cil/InstructionGroups.qll | 26 +- .../ql/src/semmle/code/cil/Instructions.qll | 86 ---- csharp/ql/src/semmle/code/cil/Method.qll | 2 - 7 files changed, 375 insertions(+), 172 deletions(-) diff --git a/csharp/ql/src/semmle/code/cil/Access.qll b/csharp/ql/src/semmle/code/cil/Access.qll index 5f956827c96d..a9835f254cd2 100644 --- a/csharp/ql/src/semmle/code/cil/Access.qll +++ b/csharp/ql/src/semmle/code/cil/Access.qll @@ -23,7 +23,6 @@ class VariableAccess extends Access, @cil_access { /** An instruction that reads a variable. */ class ReadAccess extends VariableAccess, Expr, @cil_read_access { - override Type getType() { result=getTarget().getType() } } /** An instruction yielding an address. */ diff --git a/csharp/ql/src/semmle/code/cil/ControlFlow.qll b/csharp/ql/src/semmle/code/cil/ControlFlow.qll index c4434741cbc7..1538feaa20a2 100644 --- a/csharp/ql/src/semmle/code/cil/ControlFlow.qll +++ b/csharp/ql/src/semmle/code/cil/ControlFlow.qll @@ -30,7 +30,9 @@ class ControlFlowNode extends @cil_controlflow_node final Instruction getFalseSuccessor() { result=getASuccessorType(any(FalseFlow f)) } /** Gets a successor to this node, of type `type`, if any. */ - cached Instruction getASuccessorType(FlowType t) { none() } + final Instruction getASuccessorType(FlowType t) { + result = Internal::getASuccessorByType(this, t) + } /** Gets a predecessor of this node, if any. */ ControlFlowNode getAPredecessor() { result.getASuccessor() = this } @@ -39,20 +41,7 @@ class ControlFlowNode extends @cil_controlflow_node * Gets an instruction that supplies the `i`th operand to this instruction. * Note that this can be multi-valued. */ - cached - ControlFlowNode getOperand(int i) { - // Immediate predecessor pushes the operand - i in [0 .. this.getPopCount() - 1] and - result = this.getAPredecessor() and - i < result.getPushCount() - or - // Transitive predecessor pushes the operand - exists(ControlFlowNode mid, int pushes | - this.getOperandRec(mid, i, pushes) | - pushes - mid.getStackDelta() < result.getPushCount() and - result = mid.getAPredecessor() - ) - } + ControlFlowNode getOperand(int i) { result = Internal::getOperand(this, i) } /** Gets an operand of this instruction, if any. */ ControlFlowNode getAnOperand() { result=getOperand(_) } @@ -62,33 +51,7 @@ class ControlFlowNode extends @cil_controlflow_node this=result.getAnOperand() } - /** - * Holds if `pred` is a transitive predecessor of this instruction, this - * instruction pops operand `i`, `pushes` additional pushes are required - * for operand `i` at node `pred`, and no instruction between (and including) - * `pred` and this instruction is a push for operand `i`. - */ - private predicate getOperandRec(ControlFlowNode pred, int i, int pushes) { - // Invariant: no node is a push for operand `i` - pushes >= pred.getPushCount() - and - ( - i in [0 .. this.getPopCount() - 1] and - pred = this.getAPredecessor() and - pushes = i - or - exists(ControlFlowNode mid, int pushes0 | - this.getOperandRec(mid, i, pushes0) | - pushes = pushes0 - mid.getStackDelta() and - // This is a guard to prevent ill formed programs - // and other logic errors going into an infinite loop. - pushes <= this.getImplementation().getStackSize() and - pred = mid.getAPredecessor() - ) - ) - } - - private int getStackDelta() { result = getPushCount()-getPopCount() } + int getStackDelta() { result = getPushCount() - getPopCount() } /** Gets the stack size before this instruction. */ int getStackSizeBefore() @@ -110,12 +73,380 @@ class ControlFlowNode extends @cil_controlflow_node MethodImplementation getImplementation() { none() } /** Gets the type of the item pushed onto the stack, if any. */ - cached Type getType() { none() } + Type getType() { result = Internal::getType(this) } /** Holds if this control flow node has more than one predecessor. */ predicate isJoin() { count(getAPredecessor())>1 } } +private cached module Internal { + private import Opcodes + + cached Instruction getASuccessorByType(ControlFlowNode cfn, FlowType t) { + cfn = any(Instruction i | + not i instanceof Branch and + i.canFlowNext() and + result = i.getImplementation().getInstruction(i.getIndex() + 1) and + t instanceof NormalFlow + ) + or + cfn = any(UnconditionalBranch b | + t instanceof NormalFlow and + result = b.getTarget() + ) + or + cfn = any(ConditionalBranch b | + if b instanceof Switch then + t instanceof NormalFlow and + ( + result = b.(Switch).getTarget(_) + or + result = b.getImplementation().getInstruction(b.getIndex() + 1) + ) + else ( + t instanceof TrueFlow and + result = b.getTarget() + or + t instanceof FalseFlow and + result = b.getImplementation().getInstruction(b.getIndex() + 1) + ) + ) + or + cfn = any(MethodImplementation mi | + t instanceof NormalFlow and + result.getImplementation() = mi and + result.getIndex() = 0 + ) + or + cfn = any(Handler h | + result = h.getHandlerStart() and + t instanceof NormalFlow + ) + } + + /** + * Holds if `pred` is a transitive predecessor of `cfn`, `cfn` + * pops operand `i`, `pushes` additional pushes are required + * for operand `i` at node `pred`, and no instruction between + * (and including) `pred` and `cfn` is a push for operand `i`. + */ + private predicate getOperandRec(ControlFlowNode cfn, ControlFlowNode pred, int i, int pushes) { + // Invariant: no node is a push for operand `i` + pushes >= pred.getPushCount() + and + ( + i in [0 .. cfn.getPopCount() - 1] and + pred = cfn.getAPredecessor() and + pushes = i + or + exists(ControlFlowNode mid, int pushes0 | + getOperandRec(cfn, mid, i, pushes0) | + pushes = pushes0 - mid.getStackDelta() and + // This is a guard to prevent ill formed programs + // and other logic errors going into an infinite loop. + pushes <= cfn.getImplementation().getStackSize() and + pred = mid.getAPredecessor() + ) + ) + } + + /** + * Gets an instruction that supplies the `i`th operand to this instruction. + * Note that this can be multi-valued. + */ + cached + ControlFlowNode getOperand(ControlFlowNode cfn, int i) { + // Immediate predecessor pushes the operand + i in [0 .. cfn.getPopCount() - 1] and + result = cfn.getAPredecessor() and + i < result.getPushCount() + or + // Transitive predecessor pushes the operand + exists(ControlFlowNode mid, int pushes | + getOperandRec(cfn, mid, i, pushes) | + pushes - mid.getStackDelta() < result.getPushCount() and + result = mid.getAPredecessor() + ) + } + + cached Type getType(ControlFlowNode cfn) { + cfn instanceof ComparisonOperation and + result instanceof BoolType + or + exists(Type t0, Type t1, int conversionIndex0, int conversionIndex1 | + getBinaryArithmeticExprOperandType01(cfn, t0, t1) and + conversionIndex0 = t0.getConversionIndex() and + conversionIndex1 = t1.getConversionIndex() | + t0 = t1 and result = t0 + or + conversionIndex0 < conversionIndex1 and result = t1 + or + conversionIndex0 > conversionIndex1 and result = t0 + ) + or + cfn instanceof UnaryBitwiseOperation and + // This is wrong but efficient - should depend on the types of the operands. + result instanceof IntType + or + cfn instanceof BinaryBitwiseOperation and + // This is wrong but efficient - should depend on the types of the operands. + result instanceof IntType + or + cfn instanceof IntLiteral and + result instanceof IntType + or + not cfn instanceof Newobj and + result = cfn.(Call).getTarget().getReturnType() + or + result = cfn.(ReadAccess).getTarget().getType() + or + cfn instanceof Ldnull and + result instanceof ObjectType + or + cfn instanceof Ldc_r4 and + result instanceof FloatType + or + cfn instanceof Ldc_r8 and + result instanceof DoubleType + or + result = getNegOperandType(cfn, 0) + or + result = getDupOperandType(cfn, 0) + or + cfn instanceof Ldstr and + result instanceof StringType + or + cfn instanceof Isinst and + result instanceof BoolType + or + result = cfn.(Castclass).getAccess() + or + result = cfn.(Newobj).getTarget().getDeclaringType() + or + result = cfn.(Box).getAccess() + or + result = cfn.(Unbox_any).getAccess() + or + result = cfn.(Unbox).getAccess() + or + result = cfn.(Ldobj).getAccess() + or + cfn instanceof Ldtoken and + // Not really sure what a type of a token is so use `object`. + result instanceof ObjectType + or + cfn instanceof Ldlen and + result instanceof IntType + or + // Note that this is technically wrong - it should be + // result.(ArrayType).getElementType() = getAccess() + // However the (ArrayType) may not be in the database. + result = cfn.(Newarr).getAccess() + or + result = cfn.(Ldelem).getAccess() + or + result = getLdelem_refOperandType(cfn, 1) + or + result = cfn.(Ldelema).getAccess() + or + cfn instanceof Ldelem_i and + result instanceof IntType + or + cfn instanceof Ldelem_i1 and + result instanceof SByteType + or + cfn instanceof Ldelem_i2 and + result instanceof ShortType + or + cfn instanceof Ldelem_i4 and + result instanceof IntType + or + cfn instanceof Ldelem_i8 and + result instanceof LongType + or + cfn instanceof Ldelem_r4 and + result instanceof FloatType + or + cfn instanceof Ldelem_r8 and + result instanceof DoubleType + or + cfn instanceof Ldelem_u1 and + result instanceof ByteType + or + cfn instanceof Ldelem_u2 and + result instanceof UShortType + or + cfn instanceof Ldelem_u4 and + result instanceof UIntType + or + cfn instanceof Conv_i and + result instanceof IntType + or + cfn instanceof Conv_ovf_i and + result instanceof IntType + or + cfn instanceof Conv_ovf_i_un and + result instanceof UIntType + or + cfn instanceof Conv_i1 and + result instanceof SByteType + or + cfn instanceof Conv_ovf_i1 and + result instanceof SByteType + or + cfn instanceof Conv_ovf_i1_un and + result instanceof SByteType + or + cfn instanceof Conv_i2 and + result instanceof ShortType + or + cfn instanceof Conv_ovf_i2 and + result instanceof ShortType + or + cfn instanceof Conv_ovf_i2_un and + result instanceof ShortType + or + cfn instanceof Conv_i4 and + result instanceof IntType + or + cfn instanceof Conv_ovf_i4 and + result instanceof IntType + or + cfn instanceof Conv_ovf_i4_un and + result instanceof IntType + or + cfn instanceof Conv_i8 and + result instanceof LongType + or + cfn instanceof Conv_ovf_i8 and + result instanceof LongType + or + cfn instanceof Conv_ovf_i8_un and + result instanceof LongType + or + cfn instanceof Conv_u and + result instanceof UIntType + or + cfn instanceof Conv_ovf_u and + result instanceof UIntType + or + cfn instanceof Conv_ovf_u_un and + result instanceof UIntType + or + cfn instanceof Conv_u1 and + result instanceof ByteType + or + cfn instanceof Conv_ovf_u1 and + result instanceof ByteType + or + cfn instanceof Conv_ovf_u1_un and + result instanceof ByteType + or + cfn instanceof Conv_u2 and + result instanceof UShortType + or + cfn instanceof Conv_ovf_u2 and + result instanceof UShortType + or + cfn instanceof Conv_ovf_u2_un and + result instanceof UShortType + or + cfn instanceof Conv_u4 and + result instanceof UIntType + or + cfn instanceof Conv_ovf_u4 and + result instanceof UIntType + or + cfn instanceof Conv_ovf_u4_un and + result instanceof UIntType + or + cfn instanceof Conv_u8 and + result instanceof ULongType + or + cfn instanceof Conv_ovf_u8 and + result instanceof ULongType + or + cfn instanceof Conv_ovf_u8_un and + result instanceof ULongType + or + cfn instanceof Conv_r4 and + result instanceof FloatType + or + cfn instanceof Conv_r8 and + result instanceof DoubleType + or + cfn instanceof Conv_r_un and + result instanceof DoubleType // ?? + or + cfn instanceof Ldind_i and + result instanceof IntType + or + cfn instanceof Ldind_i1 and + result instanceof SByteType + or + cfn instanceof Ldind_i2 and + result instanceof ShortType + or + cfn instanceof Ldind_i4 and + result instanceof IntType + or + cfn instanceof Ldind_i8 and + result instanceof LongType + or + cfn instanceof Ldind_r4 and + result instanceof FloatType + or + cfn instanceof Ldind_r8 and + result instanceof DoubleType + or + cfn instanceof Ldind_ref and + result instanceof ObjectType + or + cfn instanceof Ldind_u1 and + result instanceof ByteType + or + cfn instanceof Ldind_u2 and + result instanceof UShortType + or + cfn instanceof Ldind_u4 and + result instanceof UIntType + or + cfn instanceof Sizeof and + result instanceof IntType + or + result = cfn.(Mkrefany).getAccess() + or + cfn instanceof Refanytype and + result instanceof SystemType + } + + pragma [nomagic] + private Type getBinaryArithmeticExprOperandType(BinaryArithmeticExpr bae, int i) { + result = getType(bae.getOperand(i)) + } + + pragma [nomagic] + private predicate getBinaryArithmeticExprOperandType01(BinaryArithmeticExpr bae, Type t0, Type t1) { + t0 = getBinaryArithmeticExprOperandType(bae, 0).getUnderlyingType() and + t1 = getBinaryArithmeticExprOperandType(bae, 1).getUnderlyingType() + } + + pragma [nomagic] + private Type getNegOperandType(Neg n, int i) { + result = getType(n.getOperand(i)) + } + + pragma [nomagic] + private Type getDupOperandType(Dup d, int i) { + result = getType(d.getOperand(i)) + } + + pragma [nomagic] + private Type getLdelem_refOperandType(Ldelem_ref l, int i) { + result = getType(l.getOperand(i)) + } +} + /** * A control flow entry point. Either a method (`MethodImplementation`) or a handler (`Handler`). * diff --git a/csharp/ql/src/semmle/code/cil/Handler.qll b/csharp/ql/src/semmle/code/cil/Handler.qll index 4649c26bd37c..40100d4086ba 100644 --- a/csharp/ql/src/semmle/code/cil/Handler.qll +++ b/csharp/ql/src/semmle/code/cil/Handler.qll @@ -46,12 +46,6 @@ class Handler extends Element, EntryPoint, @cil_handler override string toString() { none() } - override Instruction getASuccessorType(FlowType t) { - result = getHandlerStart() - and - t instanceof NormalFlow - } - /** Gets the type of the caught exception, if any. */ Type getCaughtType() { cil_handler_type(this,result) } diff --git a/csharp/ql/src/semmle/code/cil/Instruction.qll b/csharp/ql/src/semmle/code/cil/Instruction.qll index 60d6962ad23e..d0f8f5420e77 100644 --- a/csharp/ql/src/semmle/code/cil/Instruction.qll +++ b/csharp/ql/src/semmle/code/cil/Instruction.qll @@ -38,15 +38,6 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi /** Gets the declaration accessed by this instruction, if any. */ Declaration getAccess() { cil_access(this, result) } - /** Gets a successor instruction to this instruction. */ - override Instruction getASuccessorType(FlowType t) { - t instanceof NormalFlow - and - canFlowNext() - and - result = this.getImplementation().getInstruction(getIndex()+1) - } - /** Holds if this instruction passes control flow into the next instruction. */ predicate canFlowNext() { any() } diff --git a/csharp/ql/src/semmle/code/cil/InstructionGroups.qll b/csharp/ql/src/semmle/code/cil/InstructionGroups.qll index ecda6d50cdd0..2e3e031d26bb 100644 --- a/csharp/ql/src/semmle/code/cil/InstructionGroups.qll +++ b/csharp/ql/src/semmle/code/cil/InstructionGroups.qll @@ -11,7 +11,7 @@ private import dotnet */ class Expr extends DotNet::Expr, Instruction, @cil_expr { override int getPushCount() { result=1 } - override Type getType() { result=Instruction.super.getType() } + final override Type getType() { result=Instruction.super.getType() } override Method getEnclosingCallable() { result=getImplementation().getMethod() } /** @@ -30,16 +30,11 @@ class Branch extends Instruction, @cil_jump { /** An instruction that unconditionally jumps to another instruction. */ class UnconditionalBranch extends Branch, @cil_unconditional_jump { - override Instruction getASuccessorType(FlowType t) { t instanceof NormalFlow and result=getTarget() } override predicate canFlowNext() { none() } } /** An instruction that jumps to a target based on a condition. */ class ConditionalBranch extends Branch, @cil_conditional_jump { - override Instruction getASuccessorType(FlowType t) { - t instanceof TrueFlow and result = getTarget() or - t instanceof FalseFlow and result = getImplementation().getInstruction(getIndex()+1) - } override int getPushCount() { result=0 } } @@ -57,29 +52,18 @@ class UnaryExpr extends Expr, @cil_unary_expr { /** A binary expression that compares two values. */ class ComparisonOperation extends BinaryExpr, @cil_comparison_operation { - override BoolType getType() { exists(result) } } /** A binary arithmetic expression. */ class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation { - override Type getType() { - exists(Type t0, Type t1 | t0=getOperand(0).getType().getUnderlyingType() and t1=getOperand(1).getType().getUnderlyingType() | - t0=t1 and result=t0 or - t0.getConversionIndex() < t1.getConversionIndex() and result=t1 or - t0.getConversionIndex() > t1.getConversionIndex() and result=t0) - } } /** A binary bitwise expression. */ class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation { - // This is wrong but efficient - should depend on the types of the operands. - override IntType getType() { exists(result) } } /** A unary bitwise expression. */ class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation { - // This is wrong but efficient - should depend on the types of the operands. - override IntType getType() { exists(result) } } /** A unary expression that converts a value from one primitive type to another. */ @@ -104,7 +88,6 @@ class Literal extends DotNet::Literal, Expr, @cil_literal /** An integer literal. */ class IntLiteral extends Literal, @cil_ldc_i { override string getExtra() { none() } - override IntType getType() { exists(result) } } /** An expression that pushes a `float`/`Single`. */ @@ -139,13 +122,6 @@ class Call extends Expr, DotNet::Call, @cil_call_any { override string getExtra() { result=getTarget().getQualifiedName() } - /** - * Gets the return type of the call. Methods that do not return a value - * return the `void` type, `System.Void`, although the value of `getPushCount` is - * 0 in this case. - */ - override Type getType() { result=getTarget().getReturnType() } - // The number of items popped/pushed from the stack // depends on the target of the call. override int getPopCount() { result=getTarget().getCallPopCount() } diff --git a/csharp/ql/src/semmle/code/cil/Instructions.qll b/csharp/ql/src/semmle/code/cil/Instructions.qll index 50ab98b069a4..ddc58bdb4325 100644 --- a/csharp/ql/src/semmle/code/cil/Instructions.qll +++ b/csharp/ql/src/semmle/code/cil/Instructions.qll @@ -78,19 +78,16 @@ module Opcodes override string getOpcodeName() { result = "ldnull" } override string getValue() { result="null" } override string getExtra() { none() } - override Type getType() { result instanceof ObjectType } } class Ldc_r4 extends FloatLiteral, @cil_ldc_r4 { override string getOpcodeName() { result = "ldc.r4" } override string getExtra() { result=getValue() } - override Type getType() { result instanceof FloatType } } class Ldc_r8 extends FloatLiteral, @cil_ldc_r8 { override string getOpcodeName() { result = "ldc.r8" } override string getExtra() { result=getValue() } - override Type getType() { result instanceof DoubleType } } // Arithmetic operations @@ -149,7 +146,6 @@ module Opcodes class Neg extends UnaryExpr, @cil_neg { override string getOpcodeName() { result="neg" } - override NumericType getType() { result=getOperand(0).getType() } } // Binary operations @@ -197,7 +193,6 @@ module Opcodes override string getOpcodeName() { result="dup" } override int getPopCount() { result=1 } override int getPushCount() { result=2 } // This is the only instruction that pushes 2 items - override Type getType() { result=getOperand(0).getType() } } class Ret extends Return, @cil_ret { @@ -218,7 +213,6 @@ module Opcodes class Ldstr extends Literal, @cil_ldstr { override string getOpcodeName() { result="ldstr" } override string getExtra() { result = "\"" + getValue() + "\"" } - override Type getType() { result instanceof StringType } } // Control flow @@ -331,10 +325,6 @@ module Opcodes override string getOpcodeName() { result="switch" } /** Gets the `n`th jump target of this switch. */ Instruction getTarget(int n) { cil_switch(this, n, result) } - override Instruction getASuccessorType(FlowType t) { - t instanceof NormalFlow and - (result=getTarget(_) or result=getImplementation().getInstruction(getIndex()+1)) - } override string getExtra() { result = concat(int n | exists(getTarget(n)) | getTarget(n).getIndex()+":", " ") } } @@ -395,7 +385,6 @@ module Opcodes class Isinst extends UnaryExpr, @cil_isinst { override string getOpcodeName() { result="isinst" } - override BoolType getType() { exists(result) } /** Gets the type that is being tested against. */ Type getTestedType() { result=getAccess() } override string getExtra() { result=getTestedType().getQualifiedName() } @@ -403,7 +392,6 @@ module Opcodes class Castclass extends UnaryExpr, @cil_castclass { override string getOpcodeName() { result="castclass" } - override Type getType() { result=getAccess() } /** Gets the type that is being cast to. */ Type getTestedType() { result=getAccess() } override string getExtra() { result=getTestedType().getQualifiedName() } @@ -566,7 +554,6 @@ module Opcodes override string getOpcodeName() { result = "newobj" } override int getPushCount() { result=1 } override int getPopCount() { result=count(this.getARawTargetParameter())-1 } - override Type getType() { result=this.getTarget().getDeclaringType() } override Expr getArgument(int i) { result=getRawArgument(i) } pragma [noinline] @@ -589,30 +576,24 @@ module Opcodes class Box extends UnaryExpr, @cil_box { override string getOpcodeName() { result="box" } - override Type getType() { result=getAccess() } } class Unbox_any extends UnaryExpr, @cil_unbox_any { override string getOpcodeName() { result="unbox.any" } - override Type getType() { result=getAccess() } } class Unbox extends UnaryExpr, @cil_unbox { override string getOpcodeName() { result="unbox" } - override Type getType() { result=getAccess() } } class Ldobj extends UnaryExpr, @cil_ldobj { override string getOpcodeName() { result = "ldobj" } /** Gets the type of the object. */ Type getTarget() { cil_access(this, result) } - override Type getType() { result=getAccess() } } class Ldtoken extends Expr, @cil_ldtoken { override string getOpcodeName() { result="ldtoken" } - // Not really sure what a type of a token is so use `object`. - override ObjectType getType() { exists(result) } } class Constrained extends Instruction, @cil_constrained { @@ -631,7 +612,6 @@ module Opcodes class Ldlen extends UnaryExpr, @cil_ldlen { override string getOpcodeName() { result = "ldlen" } - override IntType getType() { exists(result) } } // Arrays @@ -640,28 +620,19 @@ module Opcodes override string getOpcodeName() { result = "newarr" } override int getPushCount() { result=1 } override int getPopCount() { result=1 } - override Type getType() { - // Note that this is technically wrong - it should be - // result.(ArrayType).getElementType() = getAccess() - // However the (ArrayType) may not be in the database. - result = getAccess() - } override string getExtra() { result=getType().getQualifiedName() } } class Ldelem extends ReadArrayElement, @cil_ldelem { override string getOpcodeName() { result = "ldelem" } - override Type getType() { result=getAccess() } } class Ldelem_ref extends ReadArrayElement, @cil_ldelem_ref { override string getOpcodeName() { result="ldelem.ref" } - override Type getType() { result=getArray().getType() } } class Ldelema extends ReadArrayElement, ReadRef, @cil_ldelema { override string getOpcodeName() { result="ldelema" } - override Type getType() { result=getAccess() } } class Stelem_ref extends WriteArrayElement, @cil_stelem_ref { @@ -702,223 +673,180 @@ module Opcodes class Ldelem_i extends ReadArrayElement, @cil_ldelem_i { override string getOpcodeName() { result = "ldelem.i" } - override IntType getType() { exists(result) } } class Ldelem_i1 extends ReadArrayElement, @cil_ldelem_i1 { override string getOpcodeName() { result = "ldelem.i1" } - override SByteType getType() { exists(result) } } class Ldelem_i2 extends ReadArrayElement, @cil_ldelem_i2 { override string getOpcodeName() { result = "ldelem.i2" } - override ShortType getType() { exists(result) } } class Ldelem_i4 extends ReadArrayElement, @cil_ldelem_i4 { override string getOpcodeName() { result = "ldelem.i4" } - override IntType getType() { exists(result) } } class Ldelem_i8 extends ReadArrayElement, @cil_ldelem_i8 { override string getOpcodeName() { result = "ldelem.i8" } - override LongType getType() { exists(result) } } class Ldelem_r4 extends ReadArrayElement, @cil_ldelem_r4 { override string getOpcodeName() { result = "ldelem.r4" } - override FloatType getType() { exists(result) } } class Ldelem_r8 extends ReadArrayElement, @cil_ldelem_r8 { override string getOpcodeName() { result = "ldelem.r8" } - override DoubleType getType() { exists(result) } } class Ldelem_u1 extends ReadArrayElement, @cil_ldelem_u1 { override string getOpcodeName() { result = "ldelem.u1" } - override ByteType getType() { exists(result) } } class Ldelem_u2 extends ReadArrayElement, @cil_ldelem_u2 { override string getOpcodeName() { result = "ldelem.u2" } - override UShortType getType() { exists(result) } } class Ldelem_u4 extends ReadArrayElement, @cil_ldelem_u4 { override string getOpcodeName() { result = "ldelem.u4" } - override UIntType getType() { exists(result) } } // Conversions class Conv_i extends Conversion, @cil_conv_i { override string getOpcodeName() { result="conv.i" } - override IntType getType() { exists(result) } } class Conv_ovf_i extends Conversion, @cil_conv_ovf_i { override string getOpcodeName() { result="conv.ovf.i" } - override IntType getType() { exists(result) } } class Conv_ovf_i_un extends Conversion, @cil_conv_ovf_i_un { override string getOpcodeName() { result="conv.ovf.i.un" } - override UIntType getType() { exists(result) } } class Conv_i1 extends Conversion, @cil_conv_i1 { override string getOpcodeName() { result="conv.i1" } - override SByteType getType() { exists(result) } } class Conv_ovf_i1 extends Conversion, @cil_conv_ovf_i1 { override string getOpcodeName() { result="conv.ovf.i1" } - override SByteType getType() { exists(result) } } class Conv_ovf_i1_un extends Conversion, @cil_conv_ovf_i1_un { override string getOpcodeName() { result="conv.ovf.i1.un" } - override SByteType getType() { exists(result) } } class Conv_i2 extends Conversion, @cil_conv_i2 { override string getOpcodeName() { result="conv.i2" } - override ShortType getType() { exists(result) } } class Conv_ovf_i2 extends Conversion, @cil_conv_ovf_i2 { override string getOpcodeName() { result="conv.ovf.i2" } - override ShortType getType() { exists(result) } } class Conv_ovf_i2_un extends Conversion, @cil_conv_ovf_i2_un { override string getOpcodeName() { result="conv.ovf.i2.un" } - override ShortType getType() { exists(result) } } class Conv_i4 extends Conversion, @cil_conv_i4 { override string getOpcodeName() { result="conv.i4" } - override IntType getType() { exists(result) } } class Conv_ovf_i4 extends Conversion, @cil_conv_ovf_i4 { override string getOpcodeName() { result="conv.ovf.i4" } - override IntType getType() { exists(result) } } class Conv_ovf_i4_un extends Conversion, @cil_conv_ovf_i4_un { override string getOpcodeName() { result="conv.ovf.i4.un" } - override IntType getType() { exists(result) } } class Conv_i8 extends Conversion, @cil_conv_i8 { override string getOpcodeName() { result="conv.i8" } - override LongType getType() { exists(result) } } class Conv_ovf_i8 extends Conversion, @cil_conv_ovf_i8 { override string getOpcodeName() { result="conv.ovf.i8" } - override LongType getType() { exists(result) } } class Conv_ovf_i8_un extends Conversion, @cil_conv_ovf_i8_un { override string getOpcodeName() { result="conv.ovf.i8.un" } - override LongType getType() { exists(result) } } // Unsigned conversions class Conv_u extends Conversion, @cil_conv_u { override string getOpcodeName() { result="conv.u" } - override UIntType getType() { exists(result) } } class Conv_ovf_u extends Conversion, @cil_conv_ovf_u { override string getOpcodeName() { result="conv.ovf.u" } - override UIntType getType() { exists(result) } } class Conv_ovf_u_un extends Conversion, @cil_conv_ovf_u_un { override string getOpcodeName() { result="conv.ovf.u.un" } - override UIntType getType() { exists(result) } } class Conv_u1 extends Conversion, @cil_conv_u1 { override string getOpcodeName() { result="conv.u1" } - override ByteType getType() { exists(result) } } class Conv_ovf_u1 extends Conversion, @cil_conv_ovf_u1 { override string getOpcodeName() { result="conv.ovf.u1" } - override ByteType getType() { exists(result) } } class Conv_ovf_u1_un extends Conversion, @cil_conv_ovf_u1_un { override string getOpcodeName() { result="conv.ovf.u1.un" } - override ByteType getType() { exists(result) } } class Conv_u2 extends Conversion, @cil_conv_u2 { override string getOpcodeName() { result="conv.u2" } - override UShortType getType() { exists(result) } } class Conv_ovf_u2 extends Conversion, @cil_conv_ovf_u2 { override string getOpcodeName() { result="conv.ovf.u2" } - override UShortType getType() { exists(result) } } class Conv_ovf_u2_un extends Conversion, @cil_conv_ovf_u2_un { override string getOpcodeName() { result="conv.ovf.u2.un" } - override UShortType getType() { exists(result) } } class Conv_u4 extends Conversion, @cil_conv_u4 { override string getOpcodeName() { result="conv.u4" } - override UIntType getType() { exists(result) } } class Conv_ovf_u4 extends Conversion, @cil_conv_ovf_u4 { override string getOpcodeName() { result="conv.ovf.u4" } - override UIntType getType() { exists(result) } } class Conv_ovf_u4_un extends Conversion, @cil_conv_ovf_u4_un { override string getOpcodeName() { result="conv.ovf.u4.un" } - override UIntType getType() { exists(result) } } class Conv_u8 extends Conversion, @cil_conv_u8 { override string getOpcodeName() { result="conv.u8" } - override ULongType getType() { exists(result) } } class Conv_ovf_u8 extends Conversion, @cil_conv_ovf_u8 { override string getOpcodeName() { result="conv.ovf.u8" } - override ULongType getType() { exists(result) } } class Conv_ovf_u8_un extends Conversion, @cil_conv_ovf_u8_un { override string getOpcodeName() { result="conv.ovf.u8.un" } - override ULongType getType() { exists(result) } } // Floating point conversions class Conv_r4 extends Conversion, @cil_conv_r4 { override string getOpcodeName() { result="conv.r4" } - override FloatType getType() { exists(result) } } class Conv_r8 extends Conversion, @cil_conv_r8 { override string getOpcodeName() { result="conv.r8" } - override DoubleType getType() { exists(result) } } class Conv_r_un extends Conversion, @cil_conv_r_un { override string getOpcodeName() { result="conv.r.un" } - override DoubleType getType() { exists(result) } // ?? } class Volatile extends Instruction, @cil_volatile { @@ -929,57 +857,46 @@ module Opcodes class Ldind_i extends LoadIndirect, @cil_ldind_i { override string getOpcodeName() { result="ldind.i" } - override IntType getType() { exists(result) } } class Ldind_i1 extends LoadIndirect, @cil_ldind_i1 { override string getOpcodeName() { result="ldind.i1" } - override SByteType getType() { exists(result) } } class Ldind_i2 extends LoadIndirect, @cil_ldind_i2 { override string getOpcodeName() { result="ldind.i2" } - override ShortType getType() { exists(result) } } class Ldind_i4 extends LoadIndirect, @cil_ldind_i4 { override string getOpcodeName() { result="ldind.i4" } - override IntType getType() { exists(result) } } class Ldind_i8 extends LoadIndirect, @cil_ldind_i8 { override string getOpcodeName() { result="ldind.i8" } - override LongType getType() { exists(result) } } class Ldind_r4 extends LoadIndirect, @cil_ldind_r4 { override string getOpcodeName() { result="ldind.r4" } - override FloatType getType() { exists(result) } } class Ldind_r8 extends LoadIndirect, @cil_ldind_r8 { override string getOpcodeName() { result="ldind.r8" } - override DoubleType getType() { exists(result) } } class Ldind_ref extends LoadIndirect, @cil_ldind_ref { override string getOpcodeName() { result="ldind.ref" } - override ObjectType getType() { exists(result) } } class Ldind_u1 extends LoadIndirect, @cil_ldind_u1 { override string getOpcodeName() { result="ldind.u1" } - override ByteType getType() { exists(result) } } class Ldind_u2 extends LoadIndirect, @cil_ldind_u2 { override string getOpcodeName() { result="ldind.u2" } - override UShortType getType() { exists(result) } } class Ldind_u4 extends LoadIndirect, @cil_ldind_u4 { override string getOpcodeName() { result="ldind.u4" } - override UIntType getType() { exists(result) } } class Stind_i extends StoreIndirect, @cil_stind_i { @@ -1033,7 +950,6 @@ module Opcodes class Sizeof extends Expr, @cil_sizeof { override string getOpcodeName() { result="sizeof" } - override IntType getType() { exists(result) } } class Localloc extends Expr, @cil_localloc { @@ -1048,13 +964,11 @@ module Opcodes class Mkrefany extends Expr, @cil_mkrefany { override string getOpcodeName() { result="mkrefany" } override int getPopCount() { result=1 } - override Type getType() { result=getAccess() } } class Refanytype extends Expr, @cil_refanytype { override string getOpcodeName() { result="refanytype" } override int getPopCount() { result=1 } - override SystemType getType() { exists(result) } } class Arglist extends Expr, @cil_arglist { diff --git a/csharp/ql/src/semmle/code/cil/Method.qll b/csharp/ql/src/semmle/code/cil/Method.qll index 1cbc832b8872..d14135e1a0d7 100644 --- a/csharp/ql/src/semmle/code/cil/Method.qll +++ b/csharp/ql/src/semmle/code/cil/Method.qll @@ -51,8 +51,6 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation { /** Gets a handler in this implementation, if any. */ Handler getAHandler() { result.getImplementation()=this } - override Instruction getASuccessorType(FlowType t) { t instanceof NormalFlow and result.getImplementation()=this and result.getIndex()=0 } - /** Gets the maximum stack size of this implementation. */ int getStackSize() { cil_method_stack_size(this, result) }