mirror of
https://github.com/github/codeql.git
synced 2026-03-31 12:48:17 +02:00
C#: Update the child indices for assignments, update Assign classes to extend OperatorCall and add AssignOperation classes.
This commit is contained in:
@@ -226,7 +226,7 @@ class Property extends DeclarationWithGetSetAccessors, @property {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
Expr getInitializer() { result = this.getChildExpr(1).getChildExpr(0) }
|
||||
Expr getInitializer() { result = this.getChildExpr(1).getChildExpr(1) }
|
||||
|
||||
/**
|
||||
* Holds if this property has an initial value. For example, the initial
|
||||
|
||||
@@ -408,7 +408,7 @@ class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
final override Expr getInitializer() { result = this.getChildExpr(0).getChildExpr(0) }
|
||||
final override Expr getInitializer() { result = this.getChildExpr(0).getChildExpr(1) }
|
||||
|
||||
/**
|
||||
* Holds if this field has an initial value. For example, the initial
|
||||
|
||||
@@ -17,18 +17,14 @@ class Assignment extends BinaryOperation, @assign_expr {
|
||||
implies
|
||||
// Same as `this.(LocalVariableDeclExpr).hasInitializer()` but avoids
|
||||
// negative recursion
|
||||
expr_parent(_, 0, this)
|
||||
expr_parent(_, 1, this)
|
||||
}
|
||||
|
||||
override Expr getLeftOperand() { result = this.getChild(1) }
|
||||
|
||||
override Expr getRightOperand() { result = this.getChild(0) }
|
||||
|
||||
/** Gets the left operand of this assignment. */
|
||||
Expr getLValue() { result = this.getChild(1) }
|
||||
Expr getLValue() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the right operand of this assignment. */
|
||||
Expr getRValue() { result = this.getChild(0) }
|
||||
Expr getRValue() { result = this.getRightOperand() }
|
||||
|
||||
/** Gets the variable being assigned to, if any. */
|
||||
Variable getTargetVariable() { result.getAnAccess() = this.getLValue() }
|
||||
@@ -64,37 +60,33 @@ class AssignExpr extends Assignment, @simple_assign_expr {
|
||||
|
||||
/**
|
||||
* An assignment operation. Either an arithmetic assignment operation
|
||||
* (`AssignArithmeticOperation`), a bitwise assignment operation
|
||||
* (`AssignBitwiseOperation`), or an event assignment (`AddOrRemoveEventExpr`).
|
||||
* (`AssignArithmeticOperation`), a bitwise assignment operation or
|
||||
* (`AssignBitwiseOperation`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* a null-coalescing assignment (`AssignCoalesceExpr`).
|
||||
*/
|
||||
class AssignOperation extends Assignment, @assign_op_expr {
|
||||
override string getOperator() { none() }
|
||||
|
||||
/**
|
||||
* Gets the expanded version of this assignment operation, if any.
|
||||
*
|
||||
* For example, if this assignment operation is `x += y` then
|
||||
* the expanded assignment is `x = x + y`.
|
||||
*
|
||||
* If an expanded version exists, then it is used in the control
|
||||
* flow graph.
|
||||
* Expanded versions of compound assignments are no longer extracted.
|
||||
*/
|
||||
AssignExpr getExpandedAssignment() { expr_parent(result, 2, this) }
|
||||
deprecated AssignExpr getExpandedAssignment() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this assignment operation has an expanded version.
|
||||
*
|
||||
* For example, if this assignment operation is `x += y` then
|
||||
* it has the expanded version `x = x + y`.
|
||||
*
|
||||
* If an expanded version exists, then it is used in the control
|
||||
* flow graph.
|
||||
* Expanded versions of compound assignments are no longer extracted.
|
||||
*/
|
||||
predicate hasExpandedAssignment() { exists(this.getExpandedAssignment()) }
|
||||
deprecated predicate hasExpandedAssignment() { none() }
|
||||
|
||||
override string toString() { result = "... " + this.getOperator() + " ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* An assignment operation that corresponds to an operator call, for example `x += y` corresponds to `x = x + y`.
|
||||
*/
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, @assign_op_call_expr {
|
||||
override string toString() { result = "... " + this.getOperator() + " ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* An arithmetic assignment operation. Either an addition assignment operation
|
||||
* (`AssignAddExpr`), a subtraction assignment operation (`AssignSubExpr`), a
|
||||
@@ -102,7 +94,7 @@ class AssignOperation extends Assignment, @assign_op_expr {
|
||||
* operation (`AssignDivExpr`), or a remainder assignment operation
|
||||
* (`AssignRemExpr`).
|
||||
*/
|
||||
class AssignArithmeticOperation extends AssignOperation, @assign_arith_expr { }
|
||||
class AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { }
|
||||
|
||||
/**
|
||||
* An addition assignment operation, for example `x += y`.
|
||||
@@ -158,7 +150,7 @@ class AssignRemExpr extends AssignArithmeticOperation, @assign_rem_expr {
|
||||
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* operation (`AssignUnsignedRightShiftExpr`).
|
||||
*/
|
||||
class AssignBitwiseOperation extends AssignOperation, @assign_bitwise_expr { }
|
||||
class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { }
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment operation, for example `x &= y`.
|
||||
@@ -208,12 +200,17 @@ class AssignRightShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr {
|
||||
/**
|
||||
* An unsigned right-shift assignment operation, for example `x >>>= y`.
|
||||
*/
|
||||
class AssignUnsighedRightShiftExpr extends AssignBitwiseOperation, @assign_urshift_expr {
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseOperation, @assign_urshift_expr {
|
||||
override string getOperator() { result = ">>>=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignUnsighedRightShiftExpr" }
|
||||
override string getAPrimaryQlClass() { result = "AssignUnsignedRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `AssignUnsignedRightShiftExpr` instead.
|
||||
*/
|
||||
deprecated class AssignUnsighedRightShiftExpr = AssignUnsignedRightShiftExpr;
|
||||
|
||||
/**
|
||||
* An event assignment. Either an event addition (`AddEventExpr`) or an event
|
||||
* removal (`RemoveEventExpr`).
|
||||
@@ -222,9 +219,9 @@ class AddOrRemoveEventExpr extends AssignOperation, @assign_event_expr {
|
||||
/** Gets the event targeted by this event assignment. */
|
||||
Event getTarget() { result = this.getLValue().getTarget() }
|
||||
|
||||
override EventAccess getLValue() { result = this.getChild(1) }
|
||||
override EventAccess getLValue() { result = this.getChild(0) }
|
||||
|
||||
override Expr getRValue() { result = this.getChild(0) }
|
||||
override EventAccess getLeftOperand() { result = this.getChild(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -493,12 +493,16 @@ class ConstructorInitializer extends Call, @constructor_init_expr {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class OperatorCall extends Call, LateBindableExpr, @operator_invocation_expr {
|
||||
class OperatorCall extends Call, LateBindableExpr, @op_invoke_expr {
|
||||
override Operator getTarget() { expr_call(this, result) }
|
||||
|
||||
override Operator getARuntimeTarget() { result = Call.super.getARuntimeTarget() }
|
||||
|
||||
override string toString() { result = "call to operator " + this.getTarget().getName() }
|
||||
override string toString() {
|
||||
if this instanceof DynamicOperatorCall
|
||||
then result = "dynamic call to operator " + this.getLateBoundTargetName()
|
||||
else result = "call to operator " + this.getTarget().getName()
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "OperatorCall" }
|
||||
}
|
||||
|
||||
@@ -96,13 +96,7 @@ class DynamicMethodCall extends DynamicExpr, MethodCall {
|
||||
* Unlike an ordinary call to a user-defined operator (`OperatorCall`), the
|
||||
* target operator may not be known at compile-time (as in the example above).
|
||||
*/
|
||||
class DynamicOperatorCall extends DynamicExpr, OperatorCall {
|
||||
override string toString() {
|
||||
result = "dynamic call to operator " + this.getLateBoundTargetName()
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DynamicOperatorCall" }
|
||||
}
|
||||
class DynamicOperatorCall extends DynamicExpr, OperatorCall { }
|
||||
|
||||
/**
|
||||
* A call to a user-defined mutator operator where the operand is a `dynamic`
|
||||
|
||||
@@ -14,6 +14,7 @@ import Creation
|
||||
import Dynamic
|
||||
import Literal
|
||||
import LogicalOperation
|
||||
import Operation
|
||||
import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
@@ -65,25 +66,11 @@ class Expr extends ControlFlowElement, @expr {
|
||||
/** Gets the enclosing callable of this expression, if any. */
|
||||
override Callable getEnclosingCallable() { enclosingCallable(this, result) }
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isExpandedAssignmentRValueDescendant() {
|
||||
this =
|
||||
any(AssignOperation op).getExpandedAssignment().getRValue().getChildExpr(0).getAChildExpr()
|
||||
or
|
||||
exists(Expr parent |
|
||||
parent.isExpandedAssignmentRValueDescendant() and
|
||||
this = parent.getAChildExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression is generated by the compiler and does not appear
|
||||
* explicitly in the source code.
|
||||
*/
|
||||
final predicate isImplicit() {
|
||||
compiler_generated(this) or
|
||||
this.isExpandedAssignmentRValueDescendant()
|
||||
}
|
||||
final predicate isImplicit() { compiler_generated(this) }
|
||||
|
||||
/**
|
||||
* Gets an expression that is the result of stripping (recursively) all
|
||||
@@ -168,7 +155,7 @@ class LocalVariableDeclExpr extends Expr, @local_var_decl_expr {
|
||||
string getName() { result = this.getVariable().getName() }
|
||||
|
||||
/** Gets the initializer expression of this local variable declaration, if any. */
|
||||
Expr getInitializer() { result = this.getChild(0) }
|
||||
Expr getInitializer() { result = this.getChild(1) }
|
||||
|
||||
/** Holds if this local variable declaration has an initializer. */
|
||||
predicate hasInitializer() { exists(this.getInitializer()) }
|
||||
@@ -188,7 +175,7 @@ class LocalVariableDeclExpr extends Expr, @local_var_decl_expr {
|
||||
|
||||
/** Gets the variable access used in this declaration, if any. */
|
||||
LocalVariableAccess getAccess() {
|
||||
result = this.getChild(1) or
|
||||
result = this.getChild(0) or
|
||||
result = this // `out` argument
|
||||
}
|
||||
|
||||
|
||||
122
csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll
Normal file
122
csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Provides classes for operations that also have compound assignment forms.
|
||||
*/
|
||||
|
||||
import Expr
|
||||
|
||||
/** A binary operation that involves a null-coalescing operation. */
|
||||
abstract private class NullCoalescingOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class NullCoalescingOperation = NullCoalescingOperationImpl;
|
||||
|
||||
private class AddNullCoalescingExpr extends NullCoalescingOperationImpl instanceof NullCoalescingExpr
|
||||
{ }
|
||||
|
||||
private class AddAssignCoalesceExpr extends NullCoalescingOperationImpl instanceof AssignCoalesceExpr
|
||||
{ }
|
||||
|
||||
/** A binary operations that involves an addition operation. */
|
||||
abstract private class AddOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class AddOperation = AddOperationImpl;
|
||||
|
||||
private class AddAddExpr extends AddOperationImpl instanceof AddExpr { }
|
||||
|
||||
private class AddAssignExpr extends AddOperationImpl instanceof AssignAddExpr { }
|
||||
|
||||
/** A binary operation that involves a subtraction operation. */
|
||||
abstract private class SubOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class SubOperation = SubOperationImpl;
|
||||
|
||||
private class AddSubExpr extends SubOperationImpl instanceof SubExpr { }
|
||||
|
||||
private class AddSubAssignExpr extends SubOperationImpl instanceof AssignSubExpr { }
|
||||
|
||||
/** A binary operation that involves a multiplication operation. */
|
||||
abstract private class MulOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class MulOperation = MulOperationImpl;
|
||||
|
||||
private class AddMulExpr extends MulOperationImpl instanceof MulExpr { }
|
||||
|
||||
private class AddMulAssignExpr extends MulOperationImpl instanceof AssignMulExpr { }
|
||||
|
||||
/** A binary operation that involves a division operation. */
|
||||
abstract private class DivOperationImpl extends BinaryOperation {
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
final class DivOperation = DivOperationImpl;
|
||||
|
||||
private class AddDivExpr extends DivOperationImpl instanceof DivExpr { }
|
||||
|
||||
private class AddDivAssignExpr extends DivOperationImpl instanceof AssignDivExpr { }
|
||||
|
||||
/** A binary operation that involves a remainder operation. */
|
||||
abstract private class RemOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class RemOperation = RemOperationImpl;
|
||||
|
||||
private class AddRemExpr extends RemOperationImpl instanceof RemExpr { }
|
||||
|
||||
private class AddRemAssignExpr extends RemOperationImpl instanceof AssignRemExpr { }
|
||||
|
||||
/** A binary operation that involves a bitwise AND operation. */
|
||||
abstract private class BitwiseAndOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class BitwiseAndOperation = BitwiseAndOperationImpl;
|
||||
|
||||
private class AddBitwiseAndExpr extends BitwiseAndOperationImpl instanceof BitwiseAndExpr { }
|
||||
|
||||
private class AddAssignBitwiseAndExpr extends BitwiseAndOperationImpl instanceof AssignAndExpr { }
|
||||
|
||||
/** A binary operation that involves a bitwise OR operation. */
|
||||
abstract private class BitwiseOrOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class BitwiseOrOperation = BitwiseOrOperationImpl;
|
||||
|
||||
private class AddBitwiseOrExpr extends BitwiseOrOperationImpl instanceof BitwiseOrExpr { }
|
||||
|
||||
private class AddAssignBitwiseOrExpr extends BitwiseOrOperationImpl instanceof AssignOrExpr { }
|
||||
|
||||
/** A binary operation that involves a bitwise XOR operation. */
|
||||
abstract private class BitwiseXorOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class BitwiseXorOperation = BitwiseXorOperationImpl;
|
||||
|
||||
private class AddBitwiseXorExpr extends BitwiseXorOperationImpl instanceof BitwiseXorExpr { }
|
||||
|
||||
private class AddAssignBitwiseXorExpr extends BitwiseXorOperationImpl instanceof AssignXorExpr { }
|
||||
|
||||
/** A binary operation that involves a left shift operation. */
|
||||
abstract private class LeftShiftOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class LeftShiftOperation = LeftShiftOperationImpl;
|
||||
|
||||
private class AddLeftShiftExpr extends LeftShiftOperationImpl instanceof LeftShiftExpr { }
|
||||
|
||||
private class AddAssignLeftShiftExpr extends LeftShiftOperationImpl instanceof AssignLeftShiftExpr {
|
||||
}
|
||||
|
||||
/** A binary operation that involves a right shift operation. */
|
||||
abstract private class RightShiftOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class RightShiftOperation = RightShiftOperationImpl;
|
||||
|
||||
private class AddRightShiftExpr extends RightShiftOperationImpl instanceof RightShiftExpr { }
|
||||
|
||||
private class AddAssignRightShiftExpr extends RightShiftOperationImpl instanceof AssignRightShiftExpr
|
||||
{ }
|
||||
|
||||
/** A binary operation that involves a unsigned right shift operation. */
|
||||
abstract private class UnsignedRightShiftOperationImpl extends BinaryOperation { }
|
||||
|
||||
final class UnsignedRightShiftOperation = UnsignedRightShiftOperationImpl;
|
||||
|
||||
private class AddUnsignedRightShiftExpr extends UnsignedRightShiftOperationImpl instanceof UnsignedRightShiftExpr
|
||||
{ }
|
||||
|
||||
private class AddAssignUnsignedRightShiftExpr extends UnsignedRightShiftOperationImpl instanceof AssignUnsignedRightShiftExpr
|
||||
{ }
|
||||
Reference in New Issue
Block a user