Merge pull request #11834 from michaelnebel/csharp/operators

C# 11: Extractor and library support for Unsigned right shift.
This commit is contained in:
Michael Nebel
2023-01-13 13:21:02 +01:00
committed by GitHub
57 changed files with 10987 additions and 2383 deletions

View File

@@ -30,6 +30,7 @@ private newtype TOpcode =
TNegate() or
TShiftLeft() or
TShiftRight() or
TUnsignedShiftRight() or
TBitAnd() or
TBitOr() or
TBitXor() or
@@ -652,6 +653,15 @@ module Opcode {
final override string toString() { result = "ShiftRight" }
}
/**
* The `Opcode` for a `UnsignedShiftRightInstruction`.
*
* See the `UnsignedShiftRightInstruction` documentation for more details.
*/
class UnsignedShiftRight extends BinaryBitwiseOpcode, TUnsignedShiftRight {
final override string toString() { result = "UnsignedShiftRight" }
}
/**
* The `Opcode` for a `BitAndInstruction`.
*

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -0,0 +1,13 @@
class Expression extends @expr {
string toString() { none() }
}
class TypeOrRef extends @type_or_ref {
string toString() { none() }
}
from Expression e, int k, int kind, TypeOrRef t
where
expressions(e, k, t) and
if k = [133, 134] then kind = 106 else kind = k
select e, kind, t

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Remove unsigned right shift and unsigned right shift assignment expression kinds.
compatibility: backwards
expressions.rel: run expressions.qlo

View File

@@ -240,7 +240,7 @@ namespace Semmle.Extraction.CSharp.Entities
var callType = GetCallType(Context, node);
if (callType == CallType.Dynamic)
{
UserOperator.OperatorSymbol(method.Name, out var operatorName);
UserOperator.TryGetOperatorSymbol(method.Name, out var operatorName);
trapFile.dynamic_member_name(this, operatorName);
return;
}

View File

@@ -71,6 +71,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return ExprKind.ASSIGN_LSHIFT;
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
return ExprKind.ASSIGN_RSHIFT;
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
return ExprKind.ASSIGN_URSHIFT;
case SyntaxKind.QuestionQuestionEqualsToken:
return ExprKind.ASSIGN_COALESCE;
default:
@@ -141,6 +143,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return ExprKind.REM;
case ExprKind.ASSIGN_RSHIFT:
return ExprKind.RSHIFT;
case ExprKind.ASSIGN_URSHIFT:
return ExprKind.URSHIFT;
case ExprKind.ASSIGN_SUB:
return ExprKind.SUB;
case ExprKind.ASSIGN_XOR:

View File

@@ -50,6 +50,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case SyntaxKind.BarBarToken: return ExprKind.LOG_OR;
case SyntaxKind.GreaterThanEqualsToken: return ExprKind.GE;
case SyntaxKind.GreaterThanGreaterThanToken: return ExprKind.RSHIFT;
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return ExprKind.URSHIFT;
case SyntaxKind.LessThanLessThanToken: return ExprKind.LSHIFT;
case SyntaxKind.CaretToken: return ExprKind.BIT_XOR;
case SyntaxKind.QuestionQuestionToken: return ExprKind.NULL_COALESCING;

View File

@@ -38,6 +38,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case SyntaxKind.IsExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.RightShiftExpression:
case SyntaxKind.UnsignedRightShiftExpression:
case SyntaxKind.LeftShiftExpression:
case SyntaxKind.ExclusiveOrExpression:
case SyntaxKind.CoalesceExpression:
@@ -76,6 +77,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case SyntaxKind.ExclusiveOrAssignmentExpression:
case SyntaxKind.LeftShiftAssignmentExpression:
case SyntaxKind.RightShiftAssignmentExpression:
case SyntaxKind.UnsignedRightShiftAssignmentExpression:
case SyntaxKind.DivideAssignmentExpression:
case SyntaxKind.ModuloAssignmentExpression:
case SyntaxKind.CoalesceAssignmentExpression:

View File

@@ -61,8 +61,7 @@ namespace Semmle.Extraction.CSharp.Entities
containingType = Symbol.ContainingType;
if (containingType is not null)
{
var containingNamedType = containingType as INamedTypeSymbol;
return containingNamedType is null ||
return containingType is not INamedTypeSymbol containingNamedType ||
!containingNamedType.GetMembers(Symbol.Name).Contains(Symbol);
}
@@ -83,7 +82,7 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary>
/// <param name="methodName">The method name.</param>
/// <param name="operatorName">The converted operator name.</param>
public static bool OperatorSymbol(string methodName, out string operatorName)
public static bool TryGetOperatorSymbol(string methodName, out string operatorName)
{
var success = true;
switch (methodName)
@@ -147,6 +146,9 @@ namespace Semmle.Extraction.CSharp.Entities
case "op_RightShift":
operatorName = ">>";
break;
case "op_UnsignedRightShift":
operatorName = ">>>";
break;
case "op_LeftShift":
operatorName = "<<";
break;
@@ -166,7 +168,7 @@ namespace Semmle.Extraction.CSharp.Entities
var match = Regex.Match(methodName, "^op_Checked(.*)$");
if (match.Success)
{
OperatorSymbol("op_" + match.Groups[1], out var uncheckedName);
TryGetOperatorSymbol("op_" + match.Groups[1], out var uncheckedName);
operatorName = "checked " + uncheckedName;
break;
}
@@ -190,7 +192,7 @@ namespace Semmle.Extraction.CSharp.Entities
return OperatorSymbol(cx, method.ExplicitInterfaceImplementations.First());
var methodName = method.Name;
if (!OperatorSymbol(methodName, out var result))
if (!TryGetOperatorSymbol(methodName, out var result))
cx.ModelError(method, $"Unhandled operator name in OperatorSymbol(): '{methodName}'");
return result;
}

View File

@@ -127,6 +127,8 @@ namespace Semmle.Extraction.Kinds
WITH = 130,
LIST_PATTERN = 131,
SLICE_PATTERN = 132,
URSHIFT = 133,
ASSIGN_URSHIFT = 134,
DEFINE_SYMBOL = 999,
}
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C# 11: Added support for the unsigned right shift `>>>` and unsigned right shift assignment `>>>=` operators.

View File

@@ -636,8 +636,9 @@ class TrueOperator extends UnaryOperator {
* (`SubOperator`), a multiplication operator (`MulOperator`), a division
* operator (`DivOperator`), a remainder operator (`RemOperator`), an and
* operator (`AndOperator`), an or operator (`OrOperator`), an xor
* operator (`XorOperator`), a left shift operator (`LShiftOperator`),
* a right shift operator (`RShiftOperator`), an equals operator (`EQOperator`),
* operator (`XorOperator`), a left shift operator (`LeftShiftOperator`),
* a right shift operator (`RightShiftOperator`), an unsigned right shift
* operator(`UnsignedRightShiftOperator`), an equals operator (`EQOperator`),
* a not equals operator (`NEOperator`), a lesser than operator (`LTOperator`),
* a greater than operator (`GTOperator`), a less than or equals operator
* (`LEOperator`), or a greater than or equals operator (`GEOperator`).
@@ -791,14 +792,17 @@ class XorOperator extends BinaryOperator {
* }
* ```
*/
class LShiftOperator extends BinaryOperator {
LShiftOperator() { this.getName() = "<<" }
class LeftShiftOperator extends BinaryOperator {
LeftShiftOperator() { this.getName() = "<<" }
override string getFunctionName() { result = "op_LeftShift" }
override string getAPrimaryQlClass() { result = "LShiftOperator" }
override string getAPrimaryQlClass() { result = "LeftShiftOperator" }
}
/** DEPRECATED: Alias for LeftShiftOperator. */
deprecated class LShiftOperator = LeftShiftOperator;
/**
* A user-defined right shift operator (`>>`), for example
*
@@ -808,12 +812,32 @@ class LShiftOperator extends BinaryOperator {
* }
* ```
*/
class RShiftOperator extends BinaryOperator {
RShiftOperator() { this.getName() = ">>" }
class RightShiftOperator extends BinaryOperator {
RightShiftOperator() { this.getName() = ">>" }
override string getFunctionName() { result = "op_RightShift" }
override string getAPrimaryQlClass() { result = "RShiftOperator" }
override string getAPrimaryQlClass() { result = "RightShiftOperator" }
}
/** DEPRECATED: Alias for RightShiftOperator. */
deprecated class RShiftOperator = RightShiftOperator;
/**
* A user-defined unsigned right shift operator (`>>>`), for example
*
* ```csharp
* public static Widget operator >>>(Widget lhs, Widget rhs) {
* ...
* }
* ```
*/
class UnsignedRightShiftOperator extends BinaryOperator {
UnsignedRightShiftOperator() { this.getName() = ">>>" }
override string getFunctionName() { result = "op_UnsignedRightShift" }
override string getAPrimaryQlClass() { result = "UnsignedRightShiftOperator" }
}
/**

View File

@@ -105,7 +105,7 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
exists(ConstantIntegerExpr c, int k | k = c.getIntValue() |
e.(MulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
or
e.(LShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
e.(LeftShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
or
e.(BitwiseAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
)

View File

@@ -30,7 +30,7 @@ module Private {
class MulExpr = RU::ExprNode::MulExpr;
class LShiftExpr = RU::ExprNode::LShiftExpr;
class LeftShiftExpr = RU::ExprNode::LeftShiftExpr;
predicate guardDirectlyControlsSsaRead = RU::guardControlsSsaRead/3;

View File

@@ -391,17 +391,24 @@ module ExprNode {
}
/** A left-shift operation. */
class LShiftExpr extends BinaryOperation {
override CS::LShiftExpr e;
class LeftShiftExpr extends BinaryOperation {
override CS::LeftShiftExpr e;
override TLShiftOp getOp() { any() }
override TLeftShiftOp getOp() { any() }
}
/** A right-shift operation. */
class RShiftExpr extends BinaryOperation {
override CS::RShiftExpr e;
class RightShiftExpr extends BinaryOperation {
override CS::RightShiftExpr e;
override TRShiftOp getOp() { any() }
override TRightShiftOp getOp() { any() }
}
/** An unsigned right-shift operation. */
class UnsignedRightShiftExpr extends BinaryOperation {
override CS::UnsignedRightShiftExpr e;
override TUnsignedRightShiftOp getOp() { any() }
}
/** A conditional expression. */

View File

@@ -18,9 +18,9 @@ newtype TBinarySignOperation =
TBitAndOp() or
TBitOrOp() or
TBitXorOp() or
TLShiftOp() or
TRShiftOp() or
TURShiftOp()
TLeftShiftOp() or
TRightShiftOp() or
TUnsignedRightShiftOp()
/** Class representing expression signs (+, -, 0). */
class Sign extends TSign {
@@ -271,10 +271,10 @@ class Sign extends TSign {
or
op = TBitXorOp() and result = bitxor(s)
or
op = TLShiftOp() and result = lshift(s)
op = TLeftShiftOp() and result = lshift(s)
or
op = TRShiftOp() and result = rshift(s)
op = TRightShiftOp() and result = rshift(s)
or
op = TURShiftOp() and result = urshift(s)
op = TUnsignedRightShiftOp() and result = urshift(s)
}
}

View File

@@ -211,8 +211,9 @@ private module Impl {
not e.getExpr() instanceof BitwiseAndExpr and
not e.getExpr() instanceof BitwiseOrExpr and
not e.getExpr() instanceof BitwiseXorExpr and
not e.getExpr() instanceof LShiftExpr and
not e.getExpr() instanceof RShiftExpr and
not e.getExpr() instanceof LeftShiftExpr and
not e.getExpr() instanceof RightShiftExpr and
not e.getExpr() instanceof UnsignedRightShiftExpr and
not e.getExpr() instanceof ConditionalExpr and
not e.getExpr() instanceof RefExpr and
not e.getExpr() instanceof LocalVariableDeclAndInitExpr and

View File

@@ -150,8 +150,9 @@ class AssignRemExpr extends AssignArithmeticOperation, @assign_rem_expr {
* operation (`AssignAndExpr`), a bitwise-or assignment
* operation (`AssignOrExpr`), a bitwise exclusive-or assignment
* operation (`AssignXorExpr`), a left-shift assignment
* operation (`AssignLShiftExpr`), or a right-shift assignment
* operation (`AssignRShiftExpr`).
* operation (`AssignLeftShiftExpr`), or a right-shift assignment
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
* operation (`AssignUnsignedRightShiftExpr`).
*/
class AssignBitwiseOperation extends AssignOperation, @assign_bitwise_expr { }
@@ -185,19 +186,34 @@ class AssignXorExpr extends AssignBitwiseOperation, @assign_xor_expr {
/**
* A left-shift assignment operation, for example `x <<= y`.
*/
class AssignLShiftExpr extends AssignBitwiseOperation, @assign_lshift_expr {
class AssignLeftShiftExpr extends AssignBitwiseOperation, @assign_lshift_expr {
override string getOperator() { result = "<<=" }
override string getAPrimaryQlClass() { result = "AssignLShiftExpr" }
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
}
/** DEPRECATED: Alias for AssignLeftShipExpr. */
deprecated class AssignLShiftExpr = AssignLeftShiftExpr;
/**
* A right-shift assignment operation, for example `x >>= y`.
*/
class AssignRShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr {
class AssignRightShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr {
override string getOperator() { result = ">>=" }
override string getAPrimaryQlClass() { result = "AssignRShiftExpr" }
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignRightShiftExpr. */
deprecated class AssignRShiftExpr = AssignRightShiftExpr;
/**
* An unsigned right-shift assignment operation, for example `x >>>= y`.
*/
class AssignUnsighedRightShiftExpr extends AssignBitwiseOperation, @assign_urshift_expr {
override string getOperator() { result = ">>>=" }
override string getAPrimaryQlClass() { result = "AssignUnsighedRightShiftExpr" }
}
/**

View File

@@ -31,7 +31,8 @@ class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
* A binary bitwise operation. Either a bitwise-and operation
* (`BitwiseAndExpr`), a bitwise-or operation (`BitwiseOrExpr`),
* a bitwise exclusive-or operation (`BitwiseXorExpr`), a left-shift
* operation (`LShiftExpr`), or a right-shift operation (`RShiftExpr`).
* operation (`LeftShiftExpr`), a right-shift operation (`RightShiftExpr`),
* or an unsigned right-shift operation (`UnsignedRightShiftExpr`).
*/
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_op_expr {
override string getOperator() { none() }
@@ -40,19 +41,34 @@ class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit
/**
* A left-shift operation, for example `x << y`.
*/
class LShiftExpr extends BinaryBitwiseOperation, @lshift_expr {
class LeftShiftExpr extends BinaryBitwiseOperation, @lshift_expr {
override string getOperator() { result = "<<" }
override string getAPrimaryQlClass() { result = "LShiftExpr" }
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
}
/** DEPRECATED: Alias for LeftShiftExpr. */
deprecated class LShiftExpr = LeftShiftExpr;
/**
* A right-shift operation, for example `x >> y`.
*/
class RShiftExpr extends BinaryBitwiseOperation, @rshift_expr {
class RightShiftExpr extends BinaryBitwiseOperation, @rshift_expr {
override string getOperator() { result = ">>" }
override string getAPrimaryQlClass() { result = "RShiftExpr" }
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
}
/** DEPRECATED: Alias for RightShiftExpr. */
deprecated class RShiftExpr = RightShiftExpr;
/**
* An unsigned right-shift operation, for example `x >>> y`.
*/
class UnsignedRightShiftExpr extends BinaryBitwiseOperation, @urshift_expr {
override string getOperator() { result = ">>>" }
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
}
/**

View File

@@ -1137,6 +1137,8 @@ case @expr.kind of
/* C# 11.0 */
| 131 = @list_pattern_expr
| 132 = @slice_pattern_expr
| 133 = @urshift_expr
| 134 = @assign_urshift_expr
/* Preprocessor */
| 999 = @define_symbol_expr
;
@@ -1160,7 +1162,7 @@ case @expr.kind of
@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr
| @assign_rem_expr
@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr
| @assign_lshift_expr | @assign_rshift_expr;
| @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr;
@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr
| @method_access_expr | @type_access_expr | @dynamic_member_access_expr;
@@ -1191,7 +1193,7 @@ case @expr.kind of
@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
| @rshift_expr;
| @rshift_expr | @urshift_expr;
@un_bit_op_expr = @bit_not_expr;
@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add unsigned right shift and unsigned right shift assignment expression kinds.
compatibility: backwards

View File

@@ -30,6 +30,7 @@ private newtype TOpcode =
TNegate() or
TShiftLeft() or
TShiftRight() or
TUnsignedShiftRight() or
TBitAnd() or
TBitOr() or
TBitXor() or
@@ -652,6 +653,15 @@ module Opcode {
final override string toString() { result = "ShiftRight" }
}
/**
* The `Opcode` for a `UnsignedShiftRightInstruction`.
*
* See the `UnsignedShiftRightInstruction` documentation for more details.
*/
class UnsignedShiftRight extends BinaryBitwiseOpcode, TUnsignedShiftRight {
final override string toString() { result = "UnsignedShiftRight" }
}
/**
* The `Opcode` for a `BitAndInstruction`.
*

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -1091,9 +1091,11 @@ class TranslatedCast extends TranslatedNonConstantExpr {
}
private Opcode binaryBitwiseOpcode(BinaryBitwiseOperation expr) {
expr instanceof LShiftExpr and result instanceof Opcode::ShiftLeft
expr instanceof LeftShiftExpr and result instanceof Opcode::ShiftLeft
or
expr instanceof RShiftExpr and result instanceof Opcode::ShiftRight
expr instanceof RightShiftExpr and result instanceof Opcode::ShiftRight
or
expr instanceof UnsignedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
or
expr instanceof BitwiseAndExpr and result instanceof Opcode::BitAnd
or
@@ -1377,8 +1379,9 @@ class TranslatedAssignOperation extends TranslatedAssignment {
private Type getConvertedLeftOperandType() {
if
expr instanceof AssignLShiftExpr or
expr instanceof AssignRShiftExpr
expr instanceof AssignLeftShiftExpr or
expr instanceof AssignRightShiftExpr or
expr instanceof AssignUnsighedRightShiftExpr
then result = this.getLeftOperand().getResultType()
else
// The right operand has already been converted to the type of the op.
@@ -1416,9 +1419,11 @@ class TranslatedAssignOperation extends TranslatedAssignment {
or
expr instanceof AssignXorExpr and result instanceof Opcode::BitXor
or
expr instanceof AssignLShiftExpr and result instanceof Opcode::ShiftLeft
expr instanceof AssignLeftShiftExpr and result instanceof Opcode::ShiftLeft
or
expr instanceof AssignRShiftExpr and result instanceof Opcode::ShiftRight
expr instanceof AssignRightShiftExpr and result instanceof Opcode::ShiftRight
or
expr instanceof AssignUnsighedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -522,6 +522,8 @@ module SignAnalysisCached {
i instanceof ShiftRightInstruction and
not i.getResultType().(IntegralType) instanceof SignedIntegralType and
result = s1.urshift(s2)
or
i instanceof UnsignedShiftRightInstruction and result = s1.urshift(s2)
)
or
// use hasGuard here?

View File

@@ -118,59 +118,63 @@ array.cs:
# 20| 0: [IntLiteral] 1
assignop.cs:
# 3| [Class] AssignOp
# 4| 5: [Method] Main
# 4| -1: [TypeMention] Void
# 4| 4: [BlockStmt] {...}
# 5| 0: [LocalVariableDeclStmt] ... ...;
# 5| 0: [LocalVariableDeclAndInitExpr] Int32 a = ...
# 5| -1: [TypeMention] int
# 5| 0: [LocalVariableAccess] access to local variable a
# 5| 1: [IntLiteral] 1
# 6| 1: [LocalVariableDeclStmt] ... ...;
# 6| 0: [LocalVariableDeclAndInitExpr] Int32 c = ...
# 6| -1: [TypeMention] int
# 6| 0: [LocalVariableAccess] access to local variable c
# 6| 1: [IntLiteral] 1
# 8| 2: [ExprStmt] ...;
# 8| 0: [AssignAddExpr] ... += ...
# 5| 5: [Method] Main
# 5| -1: [TypeMention] Void
# 6| 4: [BlockStmt] {...}
# 7| 0: [LocalVariableDeclStmt] ... ...;
# 7| 0: [LocalVariableDeclAndInitExpr] Int32 a = ...
# 7| -1: [TypeMention] int
# 7| 0: [LocalVariableAccess] access to local variable a
# 7| 1: [IntLiteral] 1
# 8| 1: [LocalVariableDeclStmt] ... ...;
# 8| 0: [LocalVariableDeclAndInitExpr] Int32 c = ...
# 8| -1: [TypeMention] int
# 8| 0: [LocalVariableAccess] access to local variable c
# 8| 1: [LocalVariableAccess] access to local variable a
# 9| 3: [ExprStmt] ...;
# 9| 0: [AssignSubExpr] ... -= ...
# 9| 0: [LocalVariableAccess] access to local variable c
# 9| 1: [LocalVariableAccess] access to local variable a
# 10| 4: [ExprStmt] ...;
# 10| 0: [AssignMulExpr] ... *= ...
# 8| 1: [IntLiteral] 1
# 10| 2: [ExprStmt] ...;
# 10| 0: [AssignAddExpr] ... += ...
# 10| 0: [LocalVariableAccess] access to local variable c
# 10| 1: [LocalVariableAccess] access to local variable a
# 11| 5: [ExprStmt] ...;
# 11| 0: [AssignDivExpr] ... /= ...
# 11| 3: [ExprStmt] ...;
# 11| 0: [AssignSubExpr] ... -= ...
# 11| 0: [LocalVariableAccess] access to local variable c
# 11| 1: [LocalVariableAccess] access to local variable a
# 12| 6: [ExprStmt] ...;
# 12| 0: [AssignRemExpr] ... %= ...
# 12| 4: [ExprStmt] ...;
# 12| 0: [AssignMulExpr] ... *= ...
# 12| 0: [LocalVariableAccess] access to local variable c
# 12| 1: [LocalVariableAccess] access to local variable a
# 13| 7: [ExprStmt] ...;
# 13| 0: [AssignLShiftExpr] ... <<= ...
# 13| 5: [ExprStmt] ...;
# 13| 0: [AssignDivExpr] ... /= ...
# 13| 0: [LocalVariableAccess] access to local variable c
# 13| 1: [IntLiteral] 2
# 14| 8: [ExprStmt] ...;
# 14| 0: [AssignRShiftExpr] ... >>= ...
# 13| 1: [LocalVariableAccess] access to local variable a
# 14| 6: [ExprStmt] ...;
# 14| 0: [AssignRemExpr] ... %= ...
# 14| 0: [LocalVariableAccess] access to local variable c
# 14| 1: [IntLiteral] 2
# 15| 9: [ExprStmt] ...;
# 15| 0: [AssignAndExpr] ... &= ...
# 14| 1: [LocalVariableAccess] access to local variable a
# 15| 7: [ExprStmt] ...;
# 15| 0: [AssignLeftShiftExpr] ... <<= ...
# 15| 0: [LocalVariableAccess] access to local variable c
# 15| 1: [IntLiteral] 2
# 16| 10: [ExprStmt] ...;
# 16| 0: [AssignXorExpr] ... ^= ...
# 16| 8: [ExprStmt] ...;
# 16| 0: [AssignRightShiftExpr] ... >>= ...
# 16| 0: [LocalVariableAccess] access to local variable c
# 16| 1: [IntLiteral] 2
# 17| 11: [ExprStmt] ...;
# 17| 0: [AssignOrExpr] ... |= ...
# 17| 9: [ExprStmt] ...;
# 17| 0: [AssignAndExpr] ... &= ...
# 17| 0: [LocalVariableAccess] access to local variable c
# 17| 1: [IntLiteral] 2
# 18| 10: [ExprStmt] ...;
# 18| 0: [AssignXorExpr] ... ^= ...
# 18| 0: [LocalVariableAccess] access to local variable c
# 18| 1: [IntLiteral] 2
# 19| 11: [ExprStmt] ...;
# 19| 0: [AssignOrExpr] ... |= ...
# 19| 0: [LocalVariableAccess] access to local variable c
# 19| 1: [IntLiteral] 2
# 20| 12: [ExprStmt] ...;
# 20| 0: [AssignUnsighedRightShiftExpr] ... >>>= ...
# 20| 0: [LocalVariableAccess] access to local variable c
# 20| 1: [IntLiteral] 2
casts.cs:
# 1| [Class] Casts_A
# 5| [Class] Casts_B

View File

@@ -1,19 +1,22 @@
using System;
class AssignOp {
static void Main() {
class AssignOp
{
static void Main()
{
int a = 1;
int c = 1;
c += a;
c += a;
c -= a;
c *= a;
c *= a;
c /= a;
c %= a;
c <<= 2;
c >>= 2;
c &= 2;
c ^= 2;
c %= a;
c <<= 2;
c >>= 2;
c &= 2;
c ^= 2;
c |= 2;
c >>>= 2;
}
}

View File

@@ -145,74 +145,79 @@ array.cs:
# 13| v13_6(Void) = ExitFunction :
assignop.cs:
# 4| System.Void AssignOp.Main()
# 4| Block 0
# 4| v4_1(Void) = EnterFunction :
# 4| mu4_2(<unknown>) = AliasedDefinition :
# 5| r5_1(glval<Int32>) = VariableAddress[a] :
# 5| r5_2(Int32) = Constant[1] :
# 5| mu5_3(Int32) = Store[a] : &:r5_1, r5_2
# 6| r6_1(glval<Int32>) = VariableAddress[c] :
# 6| r6_2(Int32) = Constant[1] :
# 6| mu6_3(Int32) = Store[c] : &:r6_1, r6_2
# 8| r8_1(glval<Int32>) = VariableAddress[a] :
# 8| r8_2(Int32) = Load[a] : &:r8_1, ~m?
# 8| r8_3(glval<Int32>) = VariableAddress[c] :
# 8| r8_4(Int32) = Load[c] : &:r8_3, ~m?
# 8| r8_5(Int32) = Add : r8_4, r8_2
# 8| mu8_6(Int32) = Store[c] : &:r8_3, r8_5
# 9| r9_1(glval<Int32>) = VariableAddress[a] :
# 9| r9_2(Int32) = Load[a] : &:r9_1, ~m?
# 9| r9_3(glval<Int32>) = VariableAddress[c] :
# 9| r9_4(Int32) = Load[c] : &:r9_3, ~m?
# 9| r9_5(Int32) = Sub : r9_4, r9_2
# 9| mu9_6(Int32) = Store[c] : &:r9_3, r9_5
# 5| System.Void AssignOp.Main()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Int32>) = VariableAddress[a] :
# 7| r7_2(Int32) = Constant[1] :
# 7| mu7_3(Int32) = Store[a] : &:r7_1, r7_2
# 8| r8_1(glval<Int32>) = VariableAddress[c] :
# 8| r8_2(Int32) = Constant[1] :
# 8| mu8_3(Int32) = Store[c] : &:r8_1, r8_2
# 10| r10_1(glval<Int32>) = VariableAddress[a] :
# 10| r10_2(Int32) = Load[a] : &:r10_1, ~m?
# 10| r10_3(glval<Int32>) = VariableAddress[c] :
# 10| r10_4(Int32) = Load[c] : &:r10_3, ~m?
# 10| r10_5(Int32) = Mul : r10_4, r10_2
# 10| r10_5(Int32) = Add : r10_4, r10_2
# 10| mu10_6(Int32) = Store[c] : &:r10_3, r10_5
# 11| r11_1(glval<Int32>) = VariableAddress[a] :
# 11| r11_2(Int32) = Load[a] : &:r11_1, ~m?
# 11| r11_3(glval<Int32>) = VariableAddress[c] :
# 11| r11_4(Int32) = Load[c] : &:r11_3, ~m?
# 11| r11_5(Int32) = Div : r11_4, r11_2
# 11| r11_5(Int32) = Sub : r11_4, r11_2
# 11| mu11_6(Int32) = Store[c] : &:r11_3, r11_5
# 12| r12_1(glval<Int32>) = VariableAddress[a] :
# 12| r12_2(Int32) = Load[a] : &:r12_1, ~m?
# 12| r12_3(glval<Int32>) = VariableAddress[c] :
# 12| r12_4(Int32) = Load[c] : &:r12_3, ~m?
# 12| r12_5(Int32) = Rem : r12_4, r12_2
# 12| r12_5(Int32) = Mul : r12_4, r12_2
# 12| mu12_6(Int32) = Store[c] : &:r12_3, r12_5
# 13| r13_1(Int32) = Constant[2] :
# 13| r13_2(glval<Int32>) = VariableAddress[c] :
# 13| r13_3(Int32) = Load[c] : &:r13_2, ~m?
# 13| r13_4(Int32) = ShiftLeft : r13_3, r13_1
# 13| mu13_5(Int32) = Store[c] : &:r13_2, r13_4
# 14| r14_1(Int32) = Constant[2] :
# 14| r14_2(glval<Int32>) = VariableAddress[c] :
# 14| r14_3(Int32) = Load[c] : &:r14_2, ~m?
# 14| r14_4(Int32) = ShiftRight : r14_3, r14_1
# 14| mu14_5(Int32) = Store[c] : &:r14_2, r14_4
# 13| r13_1(glval<Int32>) = VariableAddress[a] :
# 13| r13_2(Int32) = Load[a] : &:r13_1, ~m?
# 13| r13_3(glval<Int32>) = VariableAddress[c] :
# 13| r13_4(Int32) = Load[c] : &:r13_3, ~m?
# 13| r13_5(Int32) = Div : r13_4, r13_2
# 13| mu13_6(Int32) = Store[c] : &:r13_3, r13_5
# 14| r14_1(glval<Int32>) = VariableAddress[a] :
# 14| r14_2(Int32) = Load[a] : &:r14_1, ~m?
# 14| r14_3(glval<Int32>) = VariableAddress[c] :
# 14| r14_4(Int32) = Load[c] : &:r14_3, ~m?
# 14| r14_5(Int32) = Rem : r14_4, r14_2
# 14| mu14_6(Int32) = Store[c] : &:r14_3, r14_5
# 15| r15_1(Int32) = Constant[2] :
# 15| r15_2(glval<Int32>) = VariableAddress[c] :
# 15| r15_3(Int32) = Load[c] : &:r15_2, ~m?
# 15| r15_4(Int32) = BitAnd : r15_3, r15_1
# 15| r15_4(Int32) = ShiftLeft : r15_3, r15_1
# 15| mu15_5(Int32) = Store[c] : &:r15_2, r15_4
# 16| r16_1(Int32) = Constant[2] :
# 16| r16_2(glval<Int32>) = VariableAddress[c] :
# 16| r16_3(Int32) = Load[c] : &:r16_2, ~m?
# 16| r16_4(Int32) = BitXor : r16_3, r16_1
# 16| r16_4(Int32) = ShiftRight : r16_3, r16_1
# 16| mu16_5(Int32) = Store[c] : &:r16_2, r16_4
# 17| r17_1(Int32) = Constant[2] :
# 17| r17_2(glval<Int32>) = VariableAddress[c] :
# 17| r17_3(Int32) = Load[c] : &:r17_2, ~m?
# 17| r17_4(Int32) = BitOr : r17_3, r17_1
# 17| r17_4(Int32) = BitAnd : r17_3, r17_1
# 17| mu17_5(Int32) = Store[c] : &:r17_2, r17_4
# 4| v4_3(Void) = ReturnVoid :
# 4| v4_4(Void) = AliasedUse : ~m?
# 4| v4_5(Void) = ExitFunction :
# 18| r18_1(Int32) = Constant[2] :
# 18| r18_2(glval<Int32>) = VariableAddress[c] :
# 18| r18_3(Int32) = Load[c] : &:r18_2, ~m?
# 18| r18_4(Int32) = BitXor : r18_3, r18_1
# 18| mu18_5(Int32) = Store[c] : &:r18_2, r18_4
# 19| r19_1(Int32) = Constant[2] :
# 19| r19_2(glval<Int32>) = VariableAddress[c] :
# 19| r19_3(Int32) = Load[c] : &:r19_2, ~m?
# 19| r19_4(Int32) = BitOr : r19_3, r19_1
# 19| mu19_5(Int32) = Store[c] : &:r19_2, r19_4
# 20| r20_1(Int32) = Constant[2] :
# 20| r20_2(glval<Int32>) = VariableAddress[c] :
# 20| r20_3(Int32) = Load[c] : &:r20_2, ~m?
# 20| r20_4(Int32) = UnsignedShiftRight : r20_3, r20_1
# 20| mu20_5(Int32) = Store[c] : &:r20_2, r20_4
# 5| v5_3(Void) = ReturnVoid :
# 5| v5_4(Void) = AliasedUse : ~m?
# 5| v5_5(Void) = ExitFunction :
casts.cs:
# 11| System.Void Casts.Main()

View File

@@ -0,0 +1,20 @@
public class MyClass
{
public void M1()
{
var x1 = 1;
var x2 = x1 >>> 2;
var y1 = -2;
var y2 = y1 >>> 3;
var z = -4;
z >>>= 5;
}
}
public class MyOperatorClass
{
public static MyOperatorClass operator >>>(MyOperatorClass a, MyOperatorClass b) { return null; }
}

View File

@@ -0,0 +1,42 @@
public class MySignAnalysis
{
public void UnsignedRightShiftSign(int x, int y)
{
int z;
if (x == 0)
{
z = x >>> y;
}
if (y == 0)
{
z = x >>> y;
}
if (x > 0 && y == 0)
{
z = x >>> y;
}
if (x > 0 && y > 0)
{
z = x >>> y;
}
if (x > 0 && y < 0)
{
z = x >>> y;
}
if (x < 0 && y > 0)
{
z = x >>> y;
}
if (x < 0 && y < 0)
{
z = x >>> y;
}
}
}

View File

@@ -0,0 +1,8 @@
binarybitwise
| Operators.cs:7:18:7:25 | ... >>> ... | Operators.cs:7:18:7:19 | access to local variable x1 | Operators.cs:7:25:7:25 | 2 | >>> | UnsignedRightShiftExpr |
| Operators.cs:10:18:10:25 | ... >>> ... | Operators.cs:10:18:10:19 | access to local variable y1 | Operators.cs:10:25:10:25 | 3 | >>> | UnsignedRightShiftExpr |
| Operators.cs:13:9:13:16 | ... >>> ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>> | UnsignedRightShiftExpr |
assignbitwise
| Operators.cs:13:9:13:16 | ... >>>= ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>>= | AssignUnsighedRightShiftExpr |
userdefined
| Operators.cs:19:44:19:46 | >>> | op_UnsignedRightShift | UnsignedRightShiftOperator |

View File

@@ -0,0 +1,27 @@
import csharp
query predicate binarybitwise(
BinaryBitwiseOperation op, Expr left, Expr right, string name, string qlclass
) {
op.getFile().getStem() = "Operators" and
left = op.getLeftOperand() and
right = op.getRightOperand() and
name = op.getOperator() and
qlclass = op.getAPrimaryQlClass()
}
query predicate assignbitwise(
AssignBitwiseOperation op, Expr left, Expr right, string name, string qlclass
) {
op.getFile().getStem() = "Operators" and
left = op.getLValue() and
right = op.getRValue() and
name = op.getOperator() and
qlclass = op.getAPrimaryQlClass()
}
query predicate userdefined(Operator op, string fname, string qlclass) {
op.getFile().getStem() = "Operators" and
fname = op.getFunctionName() and
qlclass = op.getAPrimaryQlClass()
}

View File

@@ -0,0 +1,7 @@
| SignAnalysis.cs:9:17:9:23 | ... >>> ... | 0 |
| SignAnalysis.cs:14:17:14:23 | ... >>> ... | + - 0 |
| SignAnalysis.cs:19:17:19:23 | ... >>> ... | + |
| SignAnalysis.cs:24:17:24:23 | ... >>> ... | + 0 |
| SignAnalysis.cs:29:17:29:23 | ... >>> ... | + 0 |
| SignAnalysis.cs:34:17:34:23 | ... >>> ... | + - |
| SignAnalysis.cs:39:17:39:23 | ... >>> ... | + - |

View File

@@ -0,0 +1,9 @@
import csharp
import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisCommon as Common
from ControlFlow::Nodes::ExprNode e, Expr expr
where
e.getExpr() = expr and
expr.getFile().getStem() = "SignAnalysis" and
expr instanceof UnsignedRightShiftExpr
select e, strictconcat(string s | s = Common::exprSign(e).toString() | s, " ")

View File

@@ -25,7 +25,7 @@ indexers.cs:
# 18| -1: [TypeMention] Int32[]
# 18| 1: [TypeMention] int
# 18| 0: [AddExpr] ... + ...
# 18| 0: [RShiftExpr] ... >> ...
# 18| 0: [RightShiftExpr] ... >> ...
# 18| 0: [SubExpr] ... - ...
# 18| 0: [ParameterAccess] access to parameter length
# 18| 1: [IntLiteral] 1
@@ -68,10 +68,10 @@ indexers.cs:
# 32| 0: [BitwiseAndExpr] ... & ...
# 32| 0: [ArrayAccess] access to array element
# 32| -1: [FieldAccess] access to field bits
# 32| 0: [RShiftExpr] ... >> ...
# 32| 0: [RightShiftExpr] ... >> ...
# 32| 0: [ParameterAccess] access to parameter index
# 32| 1: [IntLiteral] 5
# 32| 1: [LShiftExpr] ... << ...
# 32| 1: [LeftShiftExpr] ... << ...
# 32| 0: [IntLiteral] 1
# 32| 1: [ParameterAccess] access to parameter index
# 32| 1: [IntLiteral] 0
@@ -99,10 +99,10 @@ indexers.cs:
# 42| 0: [AssignOrExpr] ... |= ...
# 42| 0: [ArrayAccess] access to array element
# 42| -1: [FieldAccess] access to field bits
# 42| 0: [RShiftExpr] ... >> ...
# 42| 0: [RightShiftExpr] ... >> ...
# 42| 0: [ParameterAccess] access to parameter index
# 42| 1: [IntLiteral] 5
# 42| 1: [LShiftExpr] ... << ...
# 42| 1: [LeftShiftExpr] ... << ...
# 42| 0: [IntLiteral] 1
# 42| 1: [ParameterAccess] access to parameter index
# 45| 2: [BlockStmt] {...}
@@ -110,11 +110,11 @@ indexers.cs:
# 46| 0: [AssignAndExpr] ... &= ...
# 46| 0: [ArrayAccess] access to array element
# 46| -1: [FieldAccess] access to field bits
# 46| 0: [RShiftExpr] ... >> ...
# 46| 0: [RightShiftExpr] ... >> ...
# 46| 0: [ParameterAccess] access to parameter index
# 46| 1: [IntLiteral] 5
# 46| 1: [ComplementExpr] ~...
# 46| 0: [LShiftExpr] ... << ...
# 46| 0: [LeftShiftExpr] ... << ...
# 46| 0: [IntLiteral] 1
# 46| 1: [ParameterAccess] access to parameter index
# 53| 2: [Class] CountPrimes

View File

@@ -366,11 +366,11 @@ class CompileTimeConstantExpr extends Expr {
or
b instanceof SubExpr and result = v1 - v2
or
b instanceof LShiftExpr and result = v1.bitShiftLeft(v2)
b instanceof LeftShiftExpr and result = v1.bitShiftLeft(v2)
or
b instanceof RShiftExpr and result = v1.bitShiftRightSigned(v2)
b instanceof RightShiftExpr and result = v1.bitShiftRightSigned(v2)
or
b instanceof URShiftExpr and result = v1.bitShiftRight(v2)
b instanceof UnsignedRightShiftExpr and result = v1.bitShiftRight(v2)
or
b instanceof AndBitwiseExpr and result = v1.bitAnd(v2)
or
@@ -623,26 +623,35 @@ class AssignXorExpr extends AssignOp, @assignxorexpr {
}
/** A compound assignment expression using the `<<=` operator. */
class AssignLShiftExpr extends AssignOp, @assignlshiftexpr {
class AssignLeftShiftExpr extends AssignOp, @assignlshiftexpr {
override string getOp() { result = "<<=" }
override string getAPrimaryQlClass() { result = "AssignLShiftExpr" }
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
}
/** DEPRECATED: Alias for AssignLeftShiftExpr. */
deprecated class AssignLShiftExpr = AssignLeftShiftExpr;
/** A compound assignment expression using the `>>=` operator. */
class AssignRShiftExpr extends AssignOp, @assignrshiftexpr {
class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr {
override string getOp() { result = ">>=" }
override string getAPrimaryQlClass() { result = "AssignRShiftExpr" }
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignRightShiftExpr. */
deprecated class AssignRShiftExpr = AssignRightShiftExpr;
/** A compound assignment expression using the `>>>=` operator. */
class AssignURShiftExpr extends AssignOp, @assignurshiftexpr {
class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr {
override string getOp() { result = ">>>=" }
override string getAPrimaryQlClass() { result = "AssignURShiftExpr" }
override string getAPrimaryQlClass() { result = "AssignUnsignedRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignUnsignedRightShiftExpr. */
deprecated class AssignURShiftExpr = AssignUnsignedRightShiftExpr;
/** A common super-class to represent constant literals. */
class Literal extends Expr, @literal {
/**
@@ -904,26 +913,35 @@ class SubExpr extends BinaryExpr, @subexpr {
}
/** A binary expression using the `<<` operator. */
class LShiftExpr extends BinaryExpr, @lshiftexpr {
class LeftShiftExpr extends BinaryExpr, @lshiftexpr {
override string getOp() { result = " << " }
override string getAPrimaryQlClass() { result = "LShiftExpr" }
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
}
/** DEPRECATED: Alias for LeftShiftExpr. */
deprecated class LShiftExpr = LeftShiftExpr;
/** A binary expression using the `>>` operator. */
class RShiftExpr extends BinaryExpr, @rshiftexpr {
class RightShiftExpr extends BinaryExpr, @rshiftexpr {
override string getOp() { result = " >> " }
override string getAPrimaryQlClass() { result = "RShiftExpr" }
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
}
/** DEPRECATED: Alias for RightShiftExpr. */
deprecated class RShiftExpr = RightShiftExpr;
/** A binary expression using the `>>>` operator. */
class URShiftExpr extends BinaryExpr, @urshiftexpr {
class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr {
override string getOp() { result = " >>> " }
override string getAPrimaryQlClass() { result = "URShiftExpr" }
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
}
/** DEPRECATED: Alias for UnsignedRightShiftExpr. */
deprecated class URShiftExpr = UnsignedRightShiftExpr;
/** A binary expression using the `&` operator. */
class AndBitwiseExpr extends BinaryExpr, @andbitexpr {
override string getOp() { result = " & " }

View File

@@ -105,7 +105,7 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
exists(ConstantIntegerExpr c, int k | k = c.getIntValue() |
e.(MulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
or
e.(LShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
e.(LeftShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
or
e.(BitwiseAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
)

View File

@@ -528,11 +528,11 @@ private predicate boundFlowStepMul(Expr e2, Expr e1, int factor) {
or
exists(AssignMulExpr e | e = e2 and e.getDest() = c and e.getRhs() = e1 and factor = k)
or
exists(LShiftExpr e |
exists(LeftShiftExpr e |
e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k)
)
or
exists(AssignLShiftExpr e |
exists(AssignLeftShiftExpr e |
e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k)
)
)
@@ -552,19 +552,19 @@ private predicate boundFlowStepDiv(Expr e2, Expr e1, int factor) {
or
exists(AssignDivExpr e | e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = k)
or
exists(RShiftExpr e |
exists(RightShiftExpr e |
e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k)
)
or
exists(AssignRShiftExpr e |
exists(AssignRightShiftExpr e |
e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k)
)
or
exists(URShiftExpr e |
exists(UnsignedRightShiftExpr e |
e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k)
)
or
exists(AssignURShiftExpr e |
exists(AssignUnsignedRightShiftExpr e |
e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k)
)
)

View File

@@ -72,13 +72,13 @@ module Private {
}
/** A left shift or an assign-lshift expression. */
class LShiftExpr extends J::Expr {
LShiftExpr() { this instanceof J::LShiftExpr or this instanceof J::AssignLShiftExpr }
class LeftShiftExpr extends J::Expr {
LeftShiftExpr() { this instanceof J::LeftShiftExpr or this instanceof J::AssignLeftShiftExpr }
/** Gets the RHS operand of this shift. */
Expr getRhs() {
result = this.(J::LShiftExpr).getRightOperand() or
result = this.(J::AssignLShiftExpr).getRhs()
result = this.(J::LeftShiftExpr).getRightOperand() or
result = this.(J::AssignLeftShiftExpr).getRhs()
}
}

View File

@@ -18,9 +18,9 @@ newtype TBinarySignOperation =
TBitAndOp() or
TBitOrOp() or
TBitXorOp() or
TLShiftOp() or
TRShiftOp() or
TURShiftOp()
TLeftShiftOp() or
TRightShiftOp() or
TUnsignedRightShiftOp()
/** Class representing expression signs (+, -, 0). */
class Sign extends TSign {
@@ -271,10 +271,10 @@ class Sign extends TSign {
or
op = TBitXorOp() and result = bitxor(s)
or
op = TLShiftOp() and result = lshift(s)
op = TLeftShiftOp() and result = lshift(s)
or
op = TRShiftOp() and result = rshift(s)
op = TRightShiftOp() and result = rshift(s)
or
op = TURShiftOp() and result = urshift(s)
op = TUnsignedRightShiftOp() and result = urshift(s)
}
}

View File

@@ -102,12 +102,12 @@ module Private {
this instanceof J::AssignOrExpr or
this instanceof J::XorBitwiseExpr or
this instanceof J::AssignXorExpr or
this instanceof J::LShiftExpr or
this instanceof J::AssignLShiftExpr or
this instanceof J::RShiftExpr or
this instanceof J::AssignRShiftExpr or
this instanceof J::URShiftExpr or
this instanceof J::AssignURShiftExpr
this instanceof J::LeftShiftExpr or
this instanceof J::AssignLeftShiftExpr or
this instanceof J::RightShiftExpr or
this instanceof J::AssignRightShiftExpr or
this instanceof J::UnsignedRightShiftExpr or
this instanceof J::AssignUnsignedRightShiftExpr
}
/** Returns the operation representing this expression. */
@@ -144,17 +144,17 @@ module Private {
or
this instanceof J::AssignXorExpr and result = TBitXorOp()
or
this instanceof J::LShiftExpr and result = TLShiftOp()
this instanceof J::LeftShiftExpr and result = TLeftShiftOp()
or
this instanceof J::AssignLShiftExpr and result = TLShiftOp()
this instanceof J::AssignLeftShiftExpr and result = TLeftShiftOp()
or
this instanceof J::RShiftExpr and result = TRShiftOp()
this instanceof J::RightShiftExpr and result = TRightShiftOp()
or
this instanceof J::AssignRShiftExpr and result = TRShiftOp()
this instanceof J::AssignRightShiftExpr and result = TRightShiftOp()
or
this instanceof J::URShiftExpr and result = TURShiftOp()
this instanceof J::UnsignedRightShiftExpr and result = TUnsignedRightShiftOp()
or
this instanceof J::AssignURShiftExpr and result = TURShiftOp()
this instanceof J::AssignUnsignedRightShiftExpr and result = TUnsignedRightShiftOp()
}
Expr getLeftOperand() {

View File

@@ -14,7 +14,7 @@ int integralTypeWidth(IntegralType t) {
if t.hasName("long") or t.hasName("Long") then result = 64 else result = 32
}
from LShiftExpr shift, IntegralType t, int v, string typname, int width
from LeftShiftExpr shift, IntegralType t, int v, string typname, int width
where
shift.getLeftOperand().getType() = t and
shift.getRightOperand().(CompileTimeConstantExpr).getIntValue() = v and

View File

@@ -33,9 +33,9 @@ class ArithmeticExpr extends BinaryExpr {
*/
class ShiftExpr extends BinaryExpr {
ShiftExpr() {
this instanceof LShiftExpr or
this instanceof RShiftExpr or
this instanceof URShiftExpr
this instanceof LeftShiftExpr or
this instanceof RightShiftExpr or
this instanceof UnsignedRightShiftExpr
}
}

View File

@@ -99,7 +99,7 @@ Expr overFlowCand() {
|
bin instanceof AddExpr or
bin instanceof MulExpr or
bin instanceof LShiftExpr
bin instanceof LeftShiftExpr
)
or
exists(AssignOp op |
@@ -109,7 +109,7 @@ Expr overFlowCand() {
|
op instanceof AssignAddExpr or
op instanceof AssignMulExpr or
op instanceof AssignLShiftExpr
op instanceof AssignLeftShiftExpr
)
or
exists(AddExpr add, CompileTimeConstantExpr c |

View File

@@ -153,9 +153,9 @@ predicate upcastToWiderType(Expr e) {
/** Holds if the result of `exp` has certain bits filtered by a bitwise and. */
private predicate inBitwiseAnd(Expr exp) {
exists(AndBitwiseExpr a | a.getAnOperand() = exp) or
inBitwiseAnd(exp.(LShiftExpr).getAnOperand()) or
inBitwiseAnd(exp.(RShiftExpr).getAnOperand()) or
inBitwiseAnd(exp.(URShiftExpr).getAnOperand())
inBitwiseAnd(exp.(LeftShiftExpr).getAnOperand()) or
inBitwiseAnd(exp.(RightShiftExpr).getAnOperand()) or
inBitwiseAnd(exp.(UnsignedRightShiftExpr).getAnOperand())
}
/** Holds if overflow/underflow is irrelevant for this expression. */

View File

@@ -16,10 +16,10 @@ class NumericNarrowingCastExpr extends CastExpr {
class RightShiftOp extends Expr {
RightShiftOp() {
this instanceof RShiftExpr or
this instanceof URShiftExpr or
this instanceof AssignRShiftExpr or
this instanceof AssignURShiftExpr
this instanceof RightShiftExpr or
this instanceof UnsignedRightShiftExpr or
this instanceof AssignRightShiftExpr or
this instanceof AssignUnsignedRightShiftExpr
}
private Expr getLhs() {

View File

@@ -1944,17 +1944,17 @@ exprs.kt:
# 15| 1: [VarAccess] y
# 16| 5: [LocalVariableDeclStmt] var ...;
# 16| 1: [LocalVariableDeclExpr] i6
# 16| 0: [LShiftExpr] ... << ...
# 16| 0: [LeftShiftExpr] ... << ...
# 16| 0: [VarAccess] x
# 16| 1: [VarAccess] y
# 17| 6: [LocalVariableDeclStmt] var ...;
# 17| 1: [LocalVariableDeclExpr] i7
# 17| 0: [RShiftExpr] ... >> ...
# 17| 0: [RightShiftExpr] ... >> ...
# 17| 0: [VarAccess] x
# 17| 1: [VarAccess] y
# 18| 7: [LocalVariableDeclStmt] var ...;
# 18| 1: [LocalVariableDeclExpr] i8
# 18| 0: [URShiftExpr] ... >>> ...
# 18| 0: [UnsignedRightShiftExpr] ... >>> ...
# 18| 0: [VarAccess] x
# 18| 1: [VarAccess] y
# 19| 8: [LocalVariableDeclStmt] var ...;
@@ -2236,17 +2236,17 @@ exprs.kt:
# 72| 1: [VarAccess] ly
# 73| 59: [LocalVariableDeclStmt] var ...;
# 73| 1: [LocalVariableDeclExpr] l6
# 73| 0: [LShiftExpr] ... << ...
# 73| 0: [LeftShiftExpr] ... << ...
# 73| 0: [VarAccess] lx
# 73| 1: [VarAccess] y
# 74| 60: [LocalVariableDeclStmt] var ...;
# 74| 1: [LocalVariableDeclExpr] l7
# 74| 0: [RShiftExpr] ... >> ...
# 74| 0: [RightShiftExpr] ... >> ...
# 74| 0: [VarAccess] lx
# 74| 1: [VarAccess] y
# 75| 61: [LocalVariableDeclStmt] var ...;
# 75| 1: [LocalVariableDeclExpr] l8
# 75| 0: [URShiftExpr] ... >>> ...
# 75| 0: [UnsignedRightShiftExpr] ... >>> ...
# 75| 0: [VarAccess] lx
# 75| 1: [VarAccess] y
# 76| 62: [LocalVariableDeclStmt] var ...;

View File

@@ -924,15 +924,15 @@
| exprs.kt:15:18:15:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:16:9:16:10 | i6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:16:14:16:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:16:14:16:20 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr |
| exprs.kt:16:14:16:20 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LeftShiftExpr |
| exprs.kt:16:20:16:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:17:9:17:10 | i7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:17:14:17:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:17:14:17:20 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr |
| exprs.kt:17:14:17:20 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RightShiftExpr |
| exprs.kt:17:20:17:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:18:9:18:10 | i8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:18:14:18:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:18:14:18:21 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr |
| exprs.kt:18:14:18:21 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | UnsignedRightShiftExpr |
| exprs.kt:18:21:18:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:19:9:19:10 | i9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:19:14:19:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
@@ -1162,15 +1162,15 @@
| exprs.kt:72:19:72:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:73:9:73:10 | l6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:73:14:73:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:73:14:73:21 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr |
| exprs.kt:73:14:73:21 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LeftShiftExpr |
| exprs.kt:73:21:73:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:74:9:74:10 | l7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:74:14:74:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:74:14:74:21 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr |
| exprs.kt:74:14:74:21 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RightShiftExpr |
| exprs.kt:74:21:74:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:75:9:75:10 | l8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:75:14:75:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:75:14:75:22 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr |
| exprs.kt:75:14:75:22 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | UnsignedRightShiftExpr |
| exprs.kt:75:22:75:22 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |
| exprs.kt:76:9:76:10 | l9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:76:14:76:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess |

View File

@@ -376,26 +376,26 @@ constants/Values.java:
# 62| 43: [LocalVariableDeclStmt] var ...;
# 62| 0: [TypeAccess] int
# 62| 1: [LocalVariableDeclExpr] lshift
# 62| 0: [LShiftExpr] ... << ...
# 62| 0: [LeftShiftExpr] ... << ...
# 62| 0: [IntegerLiteral] 21
# 62| 1: [IntegerLiteral] 2
# 63| 44: [LocalVariableDeclStmt] var ...;
# 63| 0: [TypeAccess] int
# 63| 1: [LocalVariableDeclExpr] lshift_parameter
# 63| 0: [LShiftExpr] ... << ...
# 63| 0: [LeftShiftExpr] ... << ...
# 63| 0: [VarAccess] notConstant
# 63| 1: [VarAccess] notConstant
# 65| 45: [LocalVariableDeclStmt] var ...;
# 65| 0: [TypeAccess] int
# 65| 1: [LocalVariableDeclExpr] rshift
# 65| 0: [RShiftExpr] ... >> ...
# 65| 0: [RightShiftExpr] ... >> ...
# 65| 0: [MinusExpr] -...
# 65| 0: [IntegerLiteral] 1
# 65| 1: [IntegerLiteral] 2
# 66| 46: [LocalVariableDeclStmt] var ...;
# 66| 0: [TypeAccess] int
# 66| 1: [LocalVariableDeclExpr] urshift
# 66| 0: [URShiftExpr] ... >>> ...
# 66| 0: [UnsignedRightShiftExpr] ... >>> ...
# 66| 0: [MinusExpr] -...
# 66| 0: [IntegerLiteral] 1
# 66| 1: [IntegerLiteral] 1