Skip to content

Commit 5bb8f8e

Browse files
committed
C#: Support for unsigned shift right in the experimental intermediate representation.
1 parent f74c7c2 commit 5bb8f8e

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

csharp/ql/src/experimental/ir/implementation/Opcode.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ private newtype TOpcode =
3030
TNegate() or
3131
TShiftLeft() or
3232
TShiftRight() or
33+
TUnsignedShiftRight() or
3334
TBitAnd() or
3435
TBitOr() or
3536
TBitXor() or
@@ -652,6 +653,15 @@ module Opcode {
652653
final override string toString() { result = "ShiftRight" }
653654
}
654655

656+
/**
657+
* The `Opcode` for a `UnsignedShiftRightInstruction`.
658+
*
659+
* See the `UnsignedShiftRightInstruction` documentation for more details.
660+
*/
661+
class UnsignedShiftRight extends BinaryBitwiseOpcode, TUnsignedShiftRight {
662+
final override string toString() { result = "UnsignedShiftRight" }
663+
}
664+
655665
/**
656666
* The `Opcode` for a `BitAndInstruction`.
657667
*

csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
12041204
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
12051205
}
12061206

1207+
/**
1208+
* An instruction that shifts its left operand to the right by the number of bits specified by its
1209+
* right operand.
1210+
*
1211+
* Both operands must have an integer type. The result has the same type as the left operand.
1212+
* The leftmost bits are zero-filled.
1213+
*/
1214+
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
1215+
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
1216+
}
1217+
12071218
/**
12081219
* An instruction that performs a binary arithmetic operation involving at least one pointer
12091220
* operand.

csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,8 @@ private Opcode binaryBitwiseOpcode(BinaryBitwiseOperation expr) {
10951095
or
10961096
expr instanceof RightShiftExpr and result instanceof Opcode::ShiftRight
10971097
or
1098+
expr instanceof UnsignedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
1099+
or
10981100
expr instanceof BitwiseAndExpr and result instanceof Opcode::BitAnd
10991101
or
11001102
expr instanceof BitwiseOrExpr and result instanceof Opcode::BitOr
@@ -1378,7 +1380,8 @@ class TranslatedAssignOperation extends TranslatedAssignment {
13781380
private Type getConvertedLeftOperandType() {
13791381
if
13801382
expr instanceof AssignLeftShiftExpr or
1381-
expr instanceof AssignRightShiftExpr
1383+
expr instanceof AssignRightShiftExpr or
1384+
expr instanceof AssignUnsighedRightShiftExpr
13821385
then result = this.getLeftOperand().getResultType()
13831386
else
13841387
// The right operand has already been converted to the type of the op.
@@ -1419,6 +1422,8 @@ class TranslatedAssignOperation extends TranslatedAssignment {
14191422
expr instanceof AssignLeftShiftExpr and result instanceof Opcode::ShiftLeft
14201423
or
14211424
expr instanceof AssignRightShiftExpr and result instanceof Opcode::ShiftRight
1425+
or
1426+
expr instanceof AssignUnsighedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
14221427
}
14231428

14241429
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {

csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
12041204
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
12051205
}
12061206

1207+
/**
1208+
* An instruction that shifts its left operand to the right by the number of bits specified by its
1209+
* right operand.
1210+
*
1211+
* Both operands must have an integer type. The result has the same type as the left operand.
1212+
* The leftmost bits are zero-filled.
1213+
*/
1214+
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
1215+
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
1216+
}
1217+
12071218
/**
12081219
* An instruction that performs a binary arithmetic operation involving at least one pointer
12091220
* operand.

csharp/ql/src/experimental/ir/rangeanalysis/SignAnalysis.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ module SignAnalysisCached {
522522
i instanceof ShiftRightInstruction and
523523
not i.getResultType().(IntegralType) instanceof SignedIntegralType and
524524
result = s1.urshift(s2)
525+
or
526+
i instanceof UnsignedShiftRightInstruction and result = s1.urshift(s2)
525527
)
526528
or
527529
// use hasGuard here?

0 commit comments

Comments
 (0)