Skip to content

Commit 243b92b

Browse files
committed
C#: Avoid CIL instructions with multiple types
1 parent 60c0bcf commit 243b92b

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

csharp/ql/lib/semmle/code/cil/ControlFlow.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,32 @@ class ControlFlowNode extends @cil_controlflow_node {
5656
)
5757
}
5858

59+
/**
60+
* Gets the type of the `i`th operand. Unlike `getOperand(i).getType()`, this
61+
* predicate takes into account when there are multiple possible operands with
62+
* different types.
63+
*/
64+
Type getOperandType(int i) {
65+
strictcount(this.getOperand(i)) = 1 and
66+
result = this.getOperand(i).getType()
67+
or
68+
strictcount(this.getOperand(i)) = 2 and
69+
exists(ControlFlowNode op1, ControlFlowNode op2, Type t2 |
70+
op1 = this.getOperand(i) and
71+
op2 = this.getOperand(i) and
72+
op1 != op2 and
73+
result = op1.getType() and
74+
t2 = op2.getType()
75+
|
76+
result = t2
77+
or
78+
result.(PrimitiveType).getUnderlyingType().getConversionIndex() >
79+
t2.(PrimitiveType).getUnderlyingType().getConversionIndex()
80+
or
81+
op2 instanceof NullLiteral
82+
)
83+
}
84+
5985
/** Gets an operand of this instruction, if any. */
6086
ControlFlowNode getAnOperand() { result = this.getOperand(_) }
6187

csharp/ql/lib/semmle/code/cil/InstructionGroups.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
7373
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
7474
override Type getType() {
7575
exists(Type t0, Type t1 |
76-
t0 = this.getOperand(0).getType().getUnderlyingType() and
77-
t1 = this.getOperand(1).getType().getUnderlyingType()
76+
t0 = this.getOperandType(0).getUnderlyingType() and
77+
t1 = this.getOperandType(1).getUnderlyingType()
7878
|
7979
t0 = t1 and result = t0
8080
or

csharp/ql/lib/semmle/code/cil/Instructions.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ module Opcodes {
199199
override string getOpcodeName() { result = "neg" }
200200

201201
override NumericType getType() {
202-
result = this.getOperand().getType()
202+
result = this.getOperandType(0)
203203
or
204-
this.getOperand().getType() instanceof Enum and result instanceof IntType
204+
this.getOperandType(0) instanceof Enum and result instanceof IntType
205205
}
206206
}
207207

@@ -260,7 +260,7 @@ module Opcodes {
260260

261261
override int getPushCount() { result = 2 } // This is the only instruction that pushes 2 items
262262

263-
override Type getType() { result = this.getOperand(0).getType() }
263+
override Type getType() { result = this.getOperandType(0) }
264264
}
265265

266266
/** A `ret` instruction. */
@@ -887,7 +887,7 @@ module Opcodes {
887887
class Ldelem_ref extends ReadArrayElement, @cil_ldelem_ref {
888888
override string getOpcodeName() { result = "ldelem.ref" }
889889

890-
override Type getType() { result = this.getArray().getType() }
890+
override Type getType() { result = this.getOperandType(1) }
891891
}
892892

893893
/** An `ldelema` instruction. */

0 commit comments

Comments
 (0)