C#: Update the QL library implementation for Arithmetic operations.

This commit is contained in:
Michael Nebel
2026-05-29 13:05:07 +02:00
parent d101e45efc
commit 2bbcc1e88c
7 changed files with 107 additions and 93 deletions

View File

@@ -290,7 +290,7 @@ module AssignableInternal {
newtype TAssignableDefinition =
TAssignmentDefinition(Assignment a) {
not a.getLeftOperand() instanceof TupleExpr and
not a instanceof AssignCallOperation and
not a instanceof AssignCallExpr and
not a instanceof AssignCoalesceExpr
} or
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
@@ -324,7 +324,7 @@ module AssignableInternal {
TAddressOfDefinition(AddressOfExpr aoe) or
TPatternDefinition(TopLevelPatternDecl tlpd) or
TAssignOperationDefinition(AssignOperation ao) {
ao instanceof AssignCallOperation and not ao instanceof CompoundAssignmentOperatorCall
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
or
ao instanceof AssignCoalesceExpr
}

View File

@@ -912,18 +912,17 @@ module Internal {
)
or
// In C#, `null + 1` has type `int?` with value `null`
exists(BinaryOperation bo, Expr o |
bo instanceof BinaryArithmeticOperation or
bo instanceof AssignArithmeticOperation
|
result = bo and
bo.getAnOperand() = e and
bo.getAnOperand() = o and
// The other operand must be provably non-null in order
// for `only if` to hold
nonNullValueImplied(o) and
e != o
)
result =
any(BinaryArithmeticOperation bao |
exists(Expr o |
bao.getAnOperand() = e and
bao.getAnOperand() = o and
// The other operand must be provably non-null in order
// for `only if` to hold
nonNullValueImplied(o) and
e != o
)
)
}
/**
@@ -934,10 +933,10 @@ module Internal {
any(QualifiableExpr qe |
qe.isConditional() and
result = qe.getQualifier()
) or
)
or
// In C#, `null + 1` has type `int?` with value `null`
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand()) or
e = any(AssignArithmeticOperation aao | result = aao.getAnOperand())
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
}
deprecated predicate isGuard(Expr e, GuardValue val) {

View File

@@ -124,9 +124,7 @@ private module Internal {
TDispatchDynamicOperatorCall(DynamicOperatorCall doc) or
TDispatchDynamicMemberAccess(DynamicMemberAccess dma) or
TDispatchDynamicElementAccess(DynamicElementAccess dea) or
TDispatchDynamicEventAccess(
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
) {
TDispatchDynamicEventAccess(AssignArithmeticExpr aao, DynamicMemberAccess dma, string name) {
isPotentialEventCall(aao, dma, name)
} or
TDispatchDynamicObjectCreation(DynamicObjectCreation doc) or
@@ -230,7 +228,7 @@ private module Internal {
* accessor.
*/
private predicate isPotentialEventCall(
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
AssignArithmeticExpr aao, DynamicMemberAccess dma, string name
) {
aao instanceof DynamicOperatorCall and
dma = aao.getLeftOperand() and
@@ -1397,9 +1395,7 @@ private module Internal {
private class DispatchDynamicEventAccess extends DispatchReflectionOrDynamicCall,
TDispatchDynamicEventAccess
{
override AssignArithmeticOperation getCall() {
this = TDispatchDynamicEventAccess(result, _, _)
}
override AssignArithmeticExpr getCall() { this = TDispatchDynamicEventAccess(result, _, _) }
override string getName() { this = TDispatchDynamicEventAccess(_, _, result) }

View File

@@ -11,7 +11,7 @@ import Expr
* (`UnaryArithmeticOperation`) or a binary arithmetic operation
* (`BinaryArithmeticOperation`).
*/
class ArithmeticOperation extends Operation, @arith_op_expr {
class ArithmeticOperation extends Operation, @arith_operation {
override string getOperator() { none() }
}
@@ -20,7 +20,7 @@ class ArithmeticOperation extends Operation, @arith_op_expr {
* (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`),
* or a mutator operation (`MutatorOperation`).
*/
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_op_expr { }
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_operation { }
/**
* A unary minus operation, for example `-x`.
@@ -44,13 +44,13 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
* A mutator operation. Either an increment operation (`IncrementOperation`)
* or a decrement operation (`DecrementOperation`).
*/
class MutatorOperation extends UnaryArithmeticOperation, @mut_op_expr { }
class MutatorOperation extends UnaryArithmeticOperation, @mut_operation { }
/**
* An increment operation. Either a postfix increment operation
* (`PostIncrExpr`) or a prefix increment operation (`PreIncrExpr`).
*/
class IncrementOperation extends MutatorOperation, @incr_op_expr {
class IncrementOperation extends MutatorOperation, @incr_operation {
override string getOperator() { result = "++" }
}
@@ -58,7 +58,7 @@ class IncrementOperation extends MutatorOperation, @incr_op_expr {
* A decrement operation. Either a postfix decrement operation
* (`PostDecrExpr`) or a prefix decrement operation (`PreDecrExpr`).
*/
class DecrementOperation extends MutatorOperation, @decr_op_expr {
class DecrementOperation extends MutatorOperation, @decr_operation {
override string getOperator() { result = "--" }
}
@@ -95,19 +95,17 @@ class PostDecrExpr extends DecrementOperation, @post_decr_expr {
}
/**
* A binary arithmetic operation. Either an addition operation
* (`AddExpr`), a subtraction operation (`SubExpr`), a multiplication
* operation (`MulExpr`), a division operation (`DivExpr`), or a
* remainder operation (`RemExpr`).
* A binary arithmetic expression. Either an addition expression
* (`AddExpr`), a subtraction expression (`SubExpr`), a multiplication
* expression (`MulExpr`), a division expression (`DivExpr`), or a
* remainder expression (`RemExpr`).
*/
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_op_expr {
override string getOperator() { none() }
}
class BinaryArithmeticExpr extends BinaryArithmeticOperation, @bin_arith_expr { }
/**
* An addition operation, for example `x + y`.
*/
class AddExpr extends BinaryArithmeticOperation, AddOperation, @add_expr {
class AddExpr extends BinaryArithmeticExpr, AddOperation, @add_expr {
override string getOperator() { result = "+" }
override string getAPrimaryQlClass() { result = "AddExpr" }
@@ -116,7 +114,7 @@ class AddExpr extends BinaryArithmeticOperation, AddOperation, @add_expr {
/**
* A subtraction operation, for example `x - y`.
*/
class SubExpr extends BinaryArithmeticOperation, SubOperation, @sub_expr {
class SubExpr extends BinaryArithmeticExpr, SubOperation, @sub_expr {
override string getOperator() { result = "-" }
override string getAPrimaryQlClass() { result = "SubExpr" }
@@ -125,7 +123,7 @@ class SubExpr extends BinaryArithmeticOperation, SubOperation, @sub_expr {
/**
* A multiplication operation, for example `x * y`.
*/
class MulExpr extends BinaryArithmeticOperation, MulOperation, @mul_expr {
class MulExpr extends BinaryArithmeticExpr, MulOperation, @mul_expr {
override string getOperator() { result = "*" }
override string getAPrimaryQlClass() { result = "MulExpr" }
@@ -134,7 +132,7 @@ class MulExpr extends BinaryArithmeticOperation, MulOperation, @mul_expr {
/**
* A division operation, for example `x / y`.
*/
class DivExpr extends BinaryArithmeticOperation, DivOperation, @div_expr {
class DivExpr extends BinaryArithmeticExpr, DivOperation, @div_expr {
override string getOperator() { result = "/" }
override string getAPrimaryQlClass() { result = "DivExpr" }
@@ -143,7 +141,7 @@ class DivExpr extends BinaryArithmeticOperation, DivOperation, @div_expr {
/**
* A remainder operation, for example `x % y`.
*/
class RemExpr extends BinaryArithmeticOperation, RemOperation, @rem_expr {
class RemExpr extends BinaryArithmeticExpr, RemOperation, @rem_expr {
override string getOperator() { result = "%" }
override string getAPrimaryQlClass() { result = "RemExpr" }

View File

@@ -72,9 +72,9 @@ class AssignExpr extends Assignment, @simple_assign_expr {
}
/**
* An assignment operation. Either an arithmetic assignment operation
* (`AssignArithmeticOperation`), a bitwise assignment operation
* (`AssignBitwiseOperation`), an event assignment (`AddOrRemoveEventExpr`), or
* An assignment operation. Either an arithmetic assignment expression
* (`AssignArithmeticExpr`), a bitwise assignment expression
* (`AssignBitwiseExpr`), an event assignment (`AddOrRemoveEventExpr`), or
* a null-coalescing assignment (`AssignCoalesceExpr`).
*/
class AssignOperation extends Assignment, @assign_op_expr {
@@ -94,134 +94,147 @@ class AssignOperation extends Assignment, @assign_op_expr {
}
/**
* A compound assignment operation that invokes an operator.
* A compound assignment expression that invokes an operator.
*
* (1) `x += y` invokes the compound assignment operator `+=` (if it exists).
* (2) `x += y` invokes the operator `+` and assigns `x + y` to `x`.
*
* Either an arithmetic assignment operation (`AssignArithmeticOperation`) or a bitwise
* assignment operation (`AssignBitwiseOperation`).
* Either an arithmetic assignment expression (`AssignArithmeticExpr`) or a bitwise
* assignment expression (`AssignBitwiseExpr`).
*/
class AssignCallOperation extends AssignOperation, OperatorCall, QualifiableExpr,
@assign_op_call_expr
{
class AssignCallExpr extends AssignOperation, OperatorCall, QualifiableExpr, @assign_op_call_expr {
override string toString() { result = AssignOperation.super.toString() }
}
/**
* An arithmetic assignment operation. Either an addition assignment operation
* (`AssignAddExpr`), a subtraction assignment operation (`AssignSubExpr`), a
* multiplication assignment operation (`AssignMulExpr`), a division assignment
* operation (`AssignDivExpr`), or a remainder assignment operation
* (`AssignRemExpr`).
* DEPRECATED: Use `AssignCallExpr` instead.
*/
class AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { }
deprecated class AssignCallOperation = AssignCallExpr;
/**
* An addition assignment operation, for example `x += y`.
* An arithmetic assignment expression. Either an addition assignment expression
* (`AssignAddExpr`), a subtraction assignment expression (`AssignSubExpr`), a
* multiplication assignment expression (`AssignMulExpr`), a division assignment
* expression (`AssignDivExpr`), or a remainder assignment expression
* (`AssignRemExpr`).
*/
class AssignAddExpr extends AssignArithmeticOperation, AddOperation, @assign_add_expr {
class AssignArithmeticExpr extends AssignCallExpr, @assign_arith_expr { }
/**
* DEPRECATED: Use `AssignArithmeticExpr` instead.
*/
deprecated class AssignArithmeticOperation = AssignArithmeticExpr;
/**
* An addition assignment expression, for example `x += y`.
*/
class AssignAddExpr extends AssignArithmeticExpr, AddOperation, @assign_add_expr {
override string getOperator() { result = "+=" }
override string getAPrimaryQlClass() { result = "AssignAddExpr" }
}
/**
* A subtraction assignment operation, for example `x -= y`.
* A subtraction assignment expression, for example `x -= y`.
*/
class AssignSubExpr extends AssignArithmeticOperation, SubOperation, @assign_sub_expr {
class AssignSubExpr extends AssignArithmeticExpr, SubOperation, @assign_sub_expr {
override string getOperator() { result = "-=" }
override string getAPrimaryQlClass() { result = "AssignSubExpr" }
}
/**
* An multiplication assignment operation, for example `x *= y`.
* An multiplication assignment expression, for example `x *= y`.
*/
class AssignMulExpr extends AssignArithmeticOperation, MulOperation, @assign_mul_expr {
class AssignMulExpr extends AssignArithmeticExpr, MulOperation, @assign_mul_expr {
override string getOperator() { result = "*=" }
override string getAPrimaryQlClass() { result = "AssignMulExpr" }
}
/**
* An division assignment operation, for example `x /= y`.
* A division assignment expression, for example `x /= y`.
*/
class AssignDivExpr extends AssignArithmeticOperation, DivOperation, @assign_div_expr {
class AssignDivExpr extends AssignArithmeticExpr, DivOperation, @assign_div_expr {
override string getOperator() { result = "/=" }
override string getAPrimaryQlClass() { result = "AssignDivExpr" }
}
/**
* A remainder assignment operation, for example `x %= y`.
* A remainder assignment expression, for example `x %= y`.
*/
class AssignRemExpr extends AssignArithmeticOperation, RemOperation, @assign_rem_expr {
class AssignRemExpr extends AssignArithmeticExpr, RemOperation, @assign_rem_expr {
override string getOperator() { result = "%=" }
override string getAPrimaryQlClass() { result = "AssignRemExpr" }
}
/**
* A bitwise assignment operation. Either a bitwise-and assignment
* operation (`AssignAndExpr`), a bitwise-or assignment
* operation (`AssignOrExpr`), a bitwise exclusive-or assignment
* operation (`AssignXorExpr`), a left-shift assignment
* operation (`AssignLeftShiftExpr`), or a right-shift assignment
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
* operation (`AssignUnsignedRightShiftExpr`).
* A bitwise assignment expression. Either a bitwise-and assignment
* expression (`AssignAndExpr`), a bitwise-or assignment
* expression (`AssignOrExpr`), a bitwise exclusive-or assignment
* expression (`AssignXorExpr`), a left-shift assignment
* expression (`AssignLeftShiftExpr`), or a right-shift assignment
* expression (`AssignRightShiftExpr`), or an unsigned right-shift assignment
* expression (`AssignUnsignedRightShiftExpr`).
*/
class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { }
class AssignBitwiseExpr extends AssignCallExpr, @assign_bitwise_expr { }
/**
* A bitwise-and assignment operation, for example `x &= y`.
* DEPRECATED: Use `AssignBitwiseExpr` instead.
*/
class AssignAndExpr extends AssignBitwiseOperation, BitwiseAndOperation, @assign_and_expr {
deprecated class AssignBitwiseOperation = AssignBitwiseExpr;
/**
* A bitwise-and assignment expression, for example `x &= y`.
*/
class AssignAndExpr extends AssignBitwiseExpr, BitwiseAndOperation, @assign_and_expr {
override string getOperator() { result = "&=" }
override string getAPrimaryQlClass() { result = "AssignAndExpr" }
}
/**
* A bitwise-or assignment operation, for example `x |= y`.
* A bitwise-or assignment expression, for example `x |= y`.
*/
class AssignOrExpr extends AssignBitwiseOperation, BitwiseOrOperation, @assign_or_expr {
class AssignOrExpr extends AssignBitwiseExpr, BitwiseOrOperation, @assign_or_expr {
override string getOperator() { result = "|=" }
override string getAPrimaryQlClass() { result = "AssignOrExpr" }
}
/**
* A bitwise exclusive-or assignment operation, for example `x ^= y`.
* A bitwise exclusive-or assignment expression, for example `x ^= y`.
*/
class AssignXorExpr extends AssignBitwiseOperation, BitwiseXorOperation, @assign_xor_expr {
class AssignXorExpr extends AssignBitwiseExpr, BitwiseXorOperation, @assign_xor_expr {
override string getOperator() { result = "^=" }
override string getAPrimaryQlClass() { result = "AssignXorExpr" }
}
/**
* A left-shift assignment operation, for example `x <<= y`.
* A left-shift assignment expression, for example `x <<= y`.
*/
class AssignLeftShiftExpr extends AssignBitwiseOperation, LeftShiftOperation, @assign_lshift_expr {
class AssignLeftShiftExpr extends AssignBitwiseExpr, LeftShiftOperation, @assign_lshift_expr {
override string getOperator() { result = "<<=" }
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
}
/**
* A right-shift assignment operation, for example `x >>= y`.
* A right-shift assignment expression, for example `x >>= y`.
*/
class AssignRightShiftExpr extends AssignBitwiseOperation, RightShiftOperation, @assign_rshift_expr {
class AssignRightShiftExpr extends AssignBitwiseExpr, RightShiftOperation, @assign_rshift_expr {
override string getOperator() { result = ">>=" }
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
}
/**
* An unsigned right-shift assignment operation, for example `x >>>= y`.
* An unsigned right-shift assignment expression, for example `x >>>= y`.
*/
class AssignUnsignedRightShiftExpr extends AssignBitwiseOperation, UnsignedRightShiftOperation,
class AssignUnsignedRightShiftExpr extends AssignBitwiseExpr, UnsignedRightShiftOperation,
@assign_urshift_expr
{
override string getOperator() { result = ">>>=" }
@@ -297,7 +310,7 @@ class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr {
}
/**
* A null-coalescing assignment operation, for example `x ??= y`.
* A null-coalescing assignment expression, for example `x ??= y`.
*/
class AssignCoalesceExpr extends AssignOperation, NullCoalescingOperation, @assign_coalesce_expr {
override string toString() { result = "... ??= ..." }

View File

@@ -609,7 +609,7 @@ class InstanceMutatorOperatorCall extends MutatorOperatorCall {
* }
* ```
*/
class CompoundAssignmentOperatorCall extends AssignCallOperation {
class CompoundAssignmentOperatorCall extends AssignCallExpr {
CompoundAssignmentOperatorCall() { this.getTarget() instanceof CompoundAssignmentOperator }
override Expr getArgument(int i) { result = this.getChildExpr(i + 1) and i >= 0 }

View File

@@ -4,25 +4,33 @@
import Expr
/**
* A binary arithmetic operation. Either a binary arithmetic expression (`BinaryArithmeticExpr`) or
* an arithmetic assignment operation (`AssignArithmeticExpr`).
*/
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_operation {
override string getOperator() { none() }
}
/**
* An addition operation, either `x + y` or `x += y`.
*/
class AddOperation extends BinaryOperation, @add_operation { }
class AddOperation extends BinaryArithmeticOperation, @add_operation { }
/**
* A subtraction operation, either `x - y` or `x -= y`.
*/
class SubOperation extends BinaryOperation, @sub_operation { }
class SubOperation extends BinaryArithmeticOperation, @sub_operation { }
/**
* A multiplication operation, either `x * y` or `x *= y`.
*/
class MulOperation extends BinaryOperation, @mul_operation { }
class MulOperation extends BinaryArithmeticOperation, @mul_operation { }
/**
* A division operation, either `x / y` or `x /= y`.
*/
class DivOperation extends BinaryOperation, @div_operation {
class DivOperation extends BinaryArithmeticOperation, @div_operation {
/** Gets the numerator of this division operation. */
Expr getNumerator() { result = this.getLeftOperand() }
@@ -33,7 +41,7 @@ class DivOperation extends BinaryOperation, @div_operation {
/**
* A remainder operation, either `x % y` or `x %= y`.
*/
class RemOperation extends BinaryOperation, @rem_operation { }
class RemOperation extends BinaryArithmeticOperation, @rem_operation { }
/**
* A bitwise-and operation, either `x & y` or `x &= y`.