From 195b8a74e04151cfb294ea241170fcc8c077decb Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 12:52:40 +0200 Subject: [PATCH 01/11] C#: Update DB scheme for arithmetic assignments and expressions (and some other minor changes). --- csharp/ql/lib/semmlecode.csharp.dbscheme | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index 3cabc77473cb..7c7f4210399f 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -1254,12 +1254,14 @@ case @expr.kind of @delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; -@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; -@incr_op_expr = @pre_incr_expr | @post_incr_expr; -@decr_op_expr = @pre_decr_expr | @post_decr_expr; -@mut_op_expr = @incr_op_expr | @decr_op_expr; -@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; -@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; +@bin_arith_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@bin_arith_operation = @mul_operation | @div_operation | @rem_operation | @add_operation | @sub_operation; + +@incr_operation = @pre_incr_expr | @post_incr_expr; +@decr_operation = @pre_decr_expr | @post_decr_expr; +@mut_operation = @incr_operation | @decr_operation; +@un_arith_operation = @plus_expr | @minus_expr | @mut_operation; +@arith_operation = @bin_arith_operation | @un_arith_operation; @ternary_log_op_expr = @conditional_expr; @bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; @@ -1278,8 +1280,8 @@ case @expr.kind of @op_expr = @un_op | @bin_op | @ternary_op; @ternary_op = @ternary_log_op_expr; -@bin_op = @assign_expr | @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; -@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr +@bin_op = @assign_expr | @bin_arith_operation | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_operation | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr | @pointer_indirection_expr | @address_of_expr; @anonymous_function_expr = @lambda_expr | @anonymous_method_expr; From d2aa8c1356960eca75e1359af01e91fc35a68eee Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 13:05:07 +0200 Subject: [PATCH 02/11] C#: Update the QL library implementation for Arithmetic operations. --- .../ql/lib/semmle/code/csharp/Assignable.qll | 4 +- .../semmle/code/csharp/controlflow/Guards.qll | 29 +++-- .../semmle/code/csharp/dispatch/Dispatch.qll | 10 +- .../code/csharp/exprs/ArithmeticOperation.qll | 32 +++--- .../semmle/code/csharp/exprs/Assignment.qll | 103 ++++++++++-------- .../ql/lib/semmle/code/csharp/exprs/Call.qll | 2 +- .../semmle/code/csharp/exprs/Operation.qll | 18 ++- 7 files changed, 106 insertions(+), 92 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/Assignable.qll b/csharp/ql/lib/semmle/code/csharp/Assignable.qll index 7bd432d48ce4..89dc594ec3f4 100644 --- a/csharp/ql/lib/semmle/code/csharp/Assignable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Assignable.qll @@ -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 } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll index 3353866e3343..e252d855da6e 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll @@ -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) { diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll index 909ba3b9d423..c5541d5a7056 100644 --- a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll @@ -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) } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll index 193c48ed3a2b..efa038cc3a1d 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll @@ -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" } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll index f65b13bf8ecb..cafe39fb4035 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll @@ -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 + * DEPRECATED: Use `AssignCallExpr` instead. + */ +deprecated class AssignCallOperation = AssignCallExpr; + +/** + * 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 AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { } +class AssignArithmeticExpr extends AssignCallExpr, @assign_arith_expr { } + +/** + * DEPRECATED: Use `AssignArithmeticExpr` instead. + */ +deprecated class AssignArithmeticOperation = AssignArithmeticExpr; /** - * An addition assignment operation, for example `x += y`. + * An addition assignment expression, for example `x += y`. */ -class AssignAddExpr extends AssignArithmeticOperation, AddOperation, @assign_add_expr { +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 AssignBitwiseExpr extends AssignCallExpr, @assign_bitwise_expr { } + +/** + * DEPRECATED: Use `AssignBitwiseExpr` instead. */ -class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { } +deprecated class AssignBitwiseOperation = AssignBitwiseExpr; /** - * A bitwise-and assignment operation, for example `x &= y`. + * A bitwise-and assignment expression, for example `x &= y`. */ -class AssignAndExpr extends AssignBitwiseOperation, BitwiseAndOperation, @assign_and_expr { +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 = "... ??= ..." } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll index a358e73970c1..f69afb74c202 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll @@ -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 } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index 1f816baea868..09258024803c 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -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`. From 2038a077c70dc5356615ca1b7cef6f0a6c77f643 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 13:17:36 +0200 Subject: [PATCH 03/11] C#: Move arithmetic like classes from Operation.qll to ArithmeticOperation.qll. --- .../code/csharp/exprs/ArithmeticOperation.qll | 39 +++++++++++++++++++ .../semmle/code/csharp/exprs/Operation.qll | 39 ------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll index efa038cc3a1d..125419c03c9c 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll @@ -15,6 +15,14 @@ class ArithmeticOperation extends Operation, @arith_operation { override string getOperator() { none() } } +/** + * 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() } +} + /** * A unary arithmetic operation. Either a unary minus operation * (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`), @@ -94,6 +102,37 @@ class PostDecrExpr extends DecrementOperation, @post_decr_expr { override string getAPrimaryQlClass() { result = "PostDecrExpr" } } +/** + * An addition operation, either `x + y` or `x += y`. + */ +class AddOperation extends BinaryArithmeticOperation, @add_operation { } + +/** + * A subtraction operation, either `x - y` or `x -= y`. + */ +class SubOperation extends BinaryArithmeticOperation, @sub_operation { } + +/** + * A multiplication operation, either `x * y` or `x *= y`. + */ +class MulOperation extends BinaryArithmeticOperation, @mul_operation { } + +/** + * A division operation, either `x / y` or `x /= y`. + */ +class DivOperation extends BinaryArithmeticOperation, @div_operation { + /** Gets the numerator of this division operation. */ + Expr getNumerator() { result = this.getLeftOperand() } + + /** Gets the denominator of this division operation. */ + Expr getDenominator() { result = this.getRightOperand() } +} + +/** + * A remainder operation, either `x % y` or `x %= y`. + */ +class RemOperation extends BinaryArithmeticOperation, @rem_operation { } + /** * A binary arithmetic expression. Either an addition expression * (`AddExpr`), a subtraction expression (`SubExpr`), a multiplication diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index 09258024803c..b41fcfb7c7ef 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -4,45 +4,6 @@ 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 BinaryArithmeticOperation, @add_operation { } - -/** - * A subtraction operation, either `x - y` or `x -= y`. - */ -class SubOperation extends BinaryArithmeticOperation, @sub_operation { } - -/** - * A multiplication operation, either `x * y` or `x *= y`. - */ -class MulOperation extends BinaryArithmeticOperation, @mul_operation { } - -/** - * A division operation, either `x / y` or `x /= y`. - */ -class DivOperation extends BinaryArithmeticOperation, @div_operation { - /** Gets the numerator of this division operation. */ - Expr getNumerator() { result = this.getLeftOperand() } - - /** Gets the denominator of this division operation. */ - Expr getDenominator() { result = this.getRightOperand() } -} - -/** - * A remainder operation, either `x % y` or `x %= y`. - */ -class RemOperation extends BinaryArithmeticOperation, @rem_operation { } - /** * A bitwise-and operation, either `x & y` or `x &= y`. */ From 45b3f7a2d02efa645f5c6e7c37d9a4be8da36478 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 14:30:49 +0200 Subject: [PATCH 04/11] C#: Update DB scheme for bitwise assignments and expressions (and some other minor changes). --- csharp/ql/lib/semmlecode.csharp.dbscheme | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index 7c7f4210399f..7c7ae63df2e1 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -1268,21 +1268,25 @@ case @expr.kind of @un_log_op_expr = @log_not_expr; @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 | @urshift_expr; -@un_bit_op_expr = @bit_not_expr; -@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; +@bin_bit_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr | @urshift_expr; +@bin_bit_operation = @and_operation | @or_operation | @xor_operation | @lshift_operation + | @rshift_operation | @urshift_operation; +@un_bit_expr = @bit_not_expr; +@un_bit_operation = @un_bit_expr; +@bit_expr = @un_bit_expr | @bin_bit_expr; +@bit_operation = @un_bit_operation | @bin_bit_operation; @equality_op_expr = @eq_expr | @ne_expr; @rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; @comp_expr = @equality_op_expr | @rel_op_expr; -@op_expr = @un_op | @bin_op | @ternary_op; +@operation_expr = @un_operation | @bin_operation | @ternary_op; @ternary_op = @ternary_log_op_expr; -@bin_op = @assign_expr | @bin_arith_operation | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; -@un_op = @un_arith_operation | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr - | @pointer_indirection_expr | @address_of_expr; +@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_op_expr | @bin_bit_operation | @comp_expr; +@un_operation = @un_arith_operation | @un_log_op_expr | @un_bit_operation | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; @anonymous_function_expr = @lambda_expr | @anonymous_method_expr; From 80ec9972ac4a9a363d2395a33f499764eca82fbf Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 14:31:16 +0200 Subject: [PATCH 05/11] C#: Update the QL library implementation for Bitwise operations. --- .../Cryptography/NonCryptographicHashes.qll | 6 +-- .../code/csharp/exprs/BitwiseOperation.qll | 50 ++++++++++--------- .../ql/lib/semmle/code/csharp/exprs/Expr.qll | 6 +-- .../semmle/code/csharp/exprs/Operation.qll | 12 ++--- .../test/library-tests/csharp11/operators.ql | 2 +- 5 files changed, 40 insertions(+), 36 deletions(-) diff --git a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll index 130e563a6638..ae4b4ad3f611 100644 --- a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll +++ b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll @@ -50,15 +50,15 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio | add instanceof AddOperation and e1.getAChild*() = add.getAnOperand() and - e1 instanceof BinaryBitwiseOperation and - e2 = e1.(BinaryBitwiseOperation).getLeftOperand() and + e1 instanceof BinaryBitwiseExpr and + e2 = e1.(BinaryBitwiseExpr).getLeftOperand() and v = addAssign.getTargetVariable() and addAssign.getAChild*() = add and (xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and xorAssign.getAChild*() = xor and v = xorAssign.getTargetVariable() and - (notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and + (notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseExpr) and xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and notAssign.getAChild*() = notOp and v = notAssign.getTargetVariable() and diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll index 14bb3d74e2b2..ae5e8fc6e6ed 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll @@ -10,16 +10,16 @@ import Expr * A bitwise operation. Either a unary bitwise operation (`UnaryBitwiseOperation`) * or a binary bitwise operation (`BinaryBitwiseOperation`). */ -class BitwiseOperation extends Operation, @bit_expr { } +class BitwiseOperation extends Operation, @bit_operation { } /** * A unary bitwise operation, that is, a bitwise complement operation * (`ComplementExpr`). */ -class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_op_expr { } +class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_operation { } /** - * A bitwise complement operation, for example `~x`. + * A bitwise complement expression, for example `~x`. */ class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr { override string getOperator() { result = "~" } @@ -28,67 +28,71 @@ 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 (`LeftShiftExpr`), a right-shift operation (`RightShiftExpr`), - * or an unsigned right-shift operation (`UnsignedRightShiftExpr`). + * A binary bitwise operation. Either a binary bitwise expression (`BinaryBitwiseExpr`) or + * a bitwise assignment expression (`AssignBitwiseExpr`). */ -class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_op_expr { +class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_operation { override string getOperator() { none() } } /** - * A left-shift operation, for example `x << y`. + * A binary bitwise expression. Either a bitwise-and expression + * (`BitwiseAndExpr`), a bitwise-or expression (`BitwiseOrExpr`), + * a bitwise exclusive-or expression (`BitwiseXorExpr`), a left-shift + * expression (`LeftShiftExpr`), a right-shift expression (`RightShiftExpr`), + * or an unsigned right-shift expression (`UnsignedRightShiftExpr`). */ -class LeftShiftExpr extends BinaryBitwiseOperation, LeftShiftOperation, @lshift_expr { +class BinaryBitwiseExpr extends BinaryBitwiseOperation, @bin_bit_expr { } + +/** + * A left-shift expression, for example `x << y`. + */ +class LeftShiftExpr extends BinaryBitwiseExpr, LeftShiftOperation, @lshift_expr { override string getOperator() { result = "<<" } override string getAPrimaryQlClass() { result = "LeftShiftExpr" } } /** - * A right-shift operation, for example `x >> y`. + * A right-shift expression, for example `x >> y`. */ -class RightShiftExpr extends BinaryBitwiseOperation, RightShiftOperation, @rshift_expr { +class RightShiftExpr extends BinaryBitwiseExpr, RightShiftOperation, @rshift_expr { override string getOperator() { result = ">>" } override string getAPrimaryQlClass() { result = "RightShiftExpr" } } /** - * An unsigned right-shift operation, for example `x >>> y`. + * An unsigned right-shift expression, for example `x >>> y`. */ -class UnsignedRightShiftExpr extends BinaryBitwiseOperation, UnsignedRightShiftOperation, - @urshift_expr -{ +class UnsignedRightShiftExpr extends BinaryBitwiseExpr, UnsignedRightShiftOperation, @urshift_expr { override string getOperator() { result = ">>>" } override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" } } /** - * A bitwise-and operation, for example `x & y`. + * A bitwise-and expression, for example `x & y`. */ -class BitwiseAndExpr extends BinaryBitwiseOperation, BitwiseAndOperation, @bit_and_expr { +class BitwiseAndExpr extends BinaryBitwiseExpr, BitwiseAndOperation, @bit_and_expr { override string getOperator() { result = "&" } override string getAPrimaryQlClass() { result = "BitwiseAndExpr" } } /** - * A bitwise-or operation, for example `x | y`. + * A bitwise-or expression, for example `x | y`. */ -class BitwiseOrExpr extends BinaryBitwiseOperation, BitwiseOrOperation, @bit_or_expr { +class BitwiseOrExpr extends BinaryBitwiseExpr, BitwiseOrOperation, @bit_or_expr { override string getOperator() { result = "|" } override string getAPrimaryQlClass() { result = "BitwiseOrExpr" } } /** - * A bitwise exclusive-or operation, for example `x ^ y`. + * A bitwise exclusive-or expression, for example `x ^ y`. */ -class BitwiseXorExpr extends BinaryBitwiseOperation, BitwiseXorOperation, @bit_xor_expr { +class BitwiseXorExpr extends BinaryBitwiseExpr, BitwiseXorOperation, @bit_xor_expr { override string getOperator() { result = "^" } override string getAPrimaryQlClass() { result = "BitwiseXorExpr" } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll index a26afb004901..458ba7dbc0b1 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll @@ -212,7 +212,7 @@ class LocalConstantDeclExpr extends LocalVariableDeclExpr { * (`UnaryOperation`), a binary operation (`BinaryOperation`), or a * ternary operation (`TernaryOperation`). */ -class Operation extends Expr, @op_expr { +class Operation extends Expr, @operation_expr { /** Gets the name of the operator in this operation. */ string getOperator() { none() } @@ -227,7 +227,7 @@ class Operation extends Expr, @op_expr { * indirection operation (`PointerIndirectionExpr`), an address-of operation * (`AddressOfExpr`), or a unary logical operation (`UnaryLogicalOperation`). */ -class UnaryOperation extends Operation, @un_op { +class UnaryOperation extends Operation, @un_operation { /** Gets the operand of this unary operation. */ Expr getOperand() { result = this.getChild(0) } @@ -241,7 +241,7 @@ class UnaryOperation extends Operation, @un_op { * a binary logical operation (`BinaryLogicalOperation`), or an * assignment (`Assignment`). */ -class BinaryOperation extends Operation, @bin_op { +class BinaryOperation extends Operation, @bin_operation { /** Gets the left operand of this binary operation. */ Expr getLeftOperand() { result = this.getChild(0) } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index b41fcfb7c7ef..d920f169a6da 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -7,32 +7,32 @@ import Expr /** * A bitwise-and operation, either `x & y` or `x &= y`. */ -class BitwiseAndOperation extends BinaryOperation, @and_operation { } +class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { } /** * A bitwise-or operation, either `x | y` or `x |= y`. */ -class BitwiseOrOperation extends BinaryOperation, @or_operation { } +class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { } /** * A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`. */ -class BitwiseXorOperation extends BinaryOperation, @xor_operation { } +class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { } /** * A left-shift operation, either `x << y` or `x <<= y`. */ -class LeftShiftOperation extends BinaryOperation, @lshift_operation { } +class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { } /** * A right-shift operation, either `x >> y` or `x >>= y`. */ -class RightShiftOperation extends BinaryOperation, @rshift_operation { } +class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { } /** * An unsigned right-shift operation, either `x >>> y` or `x >>>= y`. */ -class UnsignedRightShiftOperation extends BinaryOperation, @urshift_operation { } +class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { } /** * A null-coalescing operation, either `x ?? y` or `x ??= y`. diff --git a/csharp/ql/test/library-tests/csharp11/operators.ql b/csharp/ql/test/library-tests/csharp11/operators.ql index f1543e2d744a..da14d2b6cb78 100644 --- a/csharp/ql/test/library-tests/csharp11/operators.ql +++ b/csharp/ql/test/library-tests/csharp11/operators.ql @@ -11,7 +11,7 @@ query predicate binarybitwise( } query predicate assignbitwise( - AssignBitwiseOperation op, Expr left, Expr right, string name, string qlclass + AssignBitwiseExpr op, Expr left, Expr right, string name, string qlclass ) { op.getFile().getStem() = "Operators" and left = op.getLeftOperand() and From 56feef812b4f79ed96df70061bec9e9180c503d2 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 14:32:10 +0200 Subject: [PATCH 06/11] C#: Update test expected output. --- csharp/ql/test/library-tests/csharp11/operators.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/test/library-tests/csharp11/operators.expected b/csharp/ql/test/library-tests/csharp11/operators.expected index 177019a3ea0c..dfd131dbfa98 100644 --- a/csharp/ql/test/library-tests/csharp11/operators.expected +++ b/csharp/ql/test/library-tests/csharp11/operators.expected @@ -1,6 +1,7 @@ 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 | >>>= | AssignUnsignedRightShiftExpr | 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 | >>>= | AssignUnsignedRightShiftExpr | userdefined From 8479063437cbfb02593d7bff0f58a2c603ce97df Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 14:42:02 +0200 Subject: [PATCH 07/11] C#: Move bitwise operation classes from Operation.qll to BitwiseOperation.qll. --- .../code/csharp/exprs/BitwiseOperation.qll | 30 +++++++++++++++++++ .../semmle/code/csharp/exprs/Operation.qll | 30 ------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll index ae5e8fc6e6ed..b6449f71a480 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll @@ -35,6 +35,36 @@ class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit override string getOperator() { none() } } +/** + * A bitwise-and operation, either `x & y` or `x &= y`. + */ +class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { } + +/** + * A bitwise-or operation, either `x | y` or `x |= y`. + */ +class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { } + +/** + * A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`. + */ +class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { } + +/** + * A left-shift operation, either `x << y` or `x <<= y`. + */ +class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { } + +/** + * A right-shift operation, either `x >> y` or `x >>= y`. + */ +class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { } + +/** + * An unsigned right-shift operation, either `x >>> y` or `x >>>= y`. + */ +class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { } + /** * A binary bitwise expression. Either a bitwise-and expression * (`BitwiseAndExpr`), a bitwise-or expression (`BitwiseOrExpr`), diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index d920f169a6da..eb1a2bea9a59 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -4,36 +4,6 @@ import Expr -/** - * A bitwise-and operation, either `x & y` or `x &= y`. - */ -class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { } - -/** - * A bitwise-or operation, either `x | y` or `x |= y`. - */ -class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { } - -/** - * A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`. - */ -class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { } - -/** - * A left-shift operation, either `x << y` or `x <<= y`. - */ -class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { } - -/** - * A right-shift operation, either `x >> y` or `x >>= y`. - */ -class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { } - -/** - * An unsigned right-shift operation, either `x >>> y` or `x >>>= y`. - */ -class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { } - /** * A null-coalescing operation, either `x ?? y` or `x ??= y`. */ From 6e0de9167ad72dc6703439fc26b5a906fa6e525b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 15:08:25 +0200 Subject: [PATCH 08/11] C#: Update DB scheme for logical assignments and expressions (and some other minor changes). --- csharp/ql/lib/semmlecode.csharp.dbscheme | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index 7c7ae63df2e1..d13c4c187d73 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -1263,10 +1263,10 @@ case @expr.kind of @un_arith_operation = @plus_expr | @minus_expr | @mut_operation; @arith_operation = @bin_arith_operation | @un_arith_operation; -@ternary_log_op_expr = @conditional_expr; -@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; -@un_log_op_expr = @log_not_expr; -@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; +@ternary_log_operation = @conditional_expr; +@bin_log_operation = @log_and_expr | @log_or_expr | @null_coalescing_operation; +@un_log_operation = @log_not_expr; +@log_operation = @un_log_operation | @bin_log_operation | @ternary_log_operation; @bin_bit_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr | @rshift_expr | @urshift_expr; @@ -1281,11 +1281,11 @@ case @expr.kind of @rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; @comp_expr = @equality_op_expr | @rel_op_expr; -@operation_expr = @un_operation | @bin_operation | @ternary_op; +@operation_expr = @un_operation | @bin_operation | @ternary_operation; -@ternary_op = @ternary_log_op_expr; -@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_op_expr | @bin_bit_operation | @comp_expr; -@un_operation = @un_arith_operation | @un_log_op_expr | @un_bit_operation | @sizeof_expr +@ternary_operation = @ternary_log_operation; +@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_operation | @bin_bit_operation | @comp_expr; +@un_operation = @un_arith_operation | @un_log_operation | @un_bit_operation | @sizeof_expr | @pointer_indirection_expr | @address_of_expr; @anonymous_function_expr = @lambda_expr | @anonymous_method_expr; From de0d239349ece5e5cdad7208fb79ebb21c4677b0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 15:09:54 +0200 Subject: [PATCH 09/11] C#: Update the QL library implementation for logical operations. --- .../lib/semmle/code/csharp/exprs/Assignment.qll | 2 +- csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll | 2 +- .../code/csharp/exprs/LogicalOperation.qll | 16 +++++++--------- .../lib/semmle/code/csharp/exprs/Operation.qll | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll index cafe39fb4035..1bd81e2ac932 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll @@ -313,7 +313,7 @@ class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr { * A null-coalescing assignment expression, for example `x ??= y`. */ class AssignCoalesceExpr extends AssignOperation, NullCoalescingOperation, @assign_coalesce_expr { - override string toString() { result = "... ??= ..." } + override string getOperator() { result = "??=" } override string getAPrimaryQlClass() { result = "AssignCoalesceExpr" } } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll index 458ba7dbc0b1..7f75a0bd31ff 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll @@ -264,7 +264,7 @@ class BinaryOperation extends Operation, @bin_operation { * A ternary operation, that is, a ternary conditional operation * (`ConditionalExpr`). */ -class TernaryOperation extends Operation, @ternary_op { } +class TernaryOperation extends Operation, @ternary_operation { } /** * A parenthesized expression, for example `(2 + 3)` in diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll index 4161f734c9b7..632352811309 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll @@ -11,14 +11,14 @@ import Expr * a binary logical operation (`BinaryLogicalOperation`), or a ternary logical * operation (`TernaryLogicalOperation`). */ -class LogicalOperation extends Operation, @log_expr { +class LogicalOperation extends Operation, @log_operation { override string getOperator() { none() } } /** * A unary logical operation, that is, a logical 'not' (`LogicalNotExpr`). */ -class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_op_expr { } +class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_operation { } /** * A logical 'not', for example `!String.IsNullOrEmpty(s)`. @@ -32,9 +32,9 @@ class LogicalNotExpr extends UnaryLogicalOperation, @log_not_expr { /** * A binary logical operation. Either a logical 'and' (`LogicalAndExpr`), * a logical 'or' (`LogicalAndExpr`), or a null-coalescing operation - * (`NullCoalescingExpr`). + * (`NullCoalescingOperation`). */ -class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_op_expr { +class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_operation { override string getOperator() { none() } } @@ -57,7 +57,7 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr { } /** - * A null-coalescing operation, for example `s ?? ""` on line 2 in + * A null-coalescing expression, for example `s ?? ""` on line 2 in * * ```csharp * string NonNullOrEmpty(string s) { @@ -65,9 +65,7 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr { * } * ``` */ -class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation, - @null_coalescing_expr -{ +class NullCoalescingExpr extends NullCoalescingOperation, @null_coalescing_expr { override string getOperator() { result = "??" } override string getAPrimaryQlClass() { result = "NullCoalescingExpr" } @@ -77,7 +75,7 @@ class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation * A ternary logical operation, that is, a ternary conditional expression * (`ConditionalExpr`). */ -class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_op_expr { } +class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_operation { } /** * A conditional expression, for example `s != null ? s.Length : -1` diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index eb1a2bea9a59..43ad205b88c4 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -7,4 +7,4 @@ import Expr /** * A null-coalescing operation, either `x ?? y` or `x ??= y`. */ -class NullCoalescingOperation extends BinaryOperation, @null_coalescing_operation { } +class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { } From b6c1eeaad3c01a98a7fbefb41517c9d241a830c9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 15:11:34 +0200 Subject: [PATCH 10/11] C#: Move logical operation class from Operation.qll to LogicalOperation.qll. --- csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll | 5 +++++ csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll index 632352811309..d16dd0446aee 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/LogicalOperation.qll @@ -56,6 +56,11 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr { override string getAPrimaryQlClass() { result = "LogicalOrExpr" } } +/** + * A null-coalescing operation, either `x ?? y` or `x ??= y`. + */ +class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { } + /** * A null-coalescing expression, for example `s ?? ""` on line 2 in * diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index 43ad205b88c4..9e43afc856cd 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -3,8 +3,3 @@ */ import Expr - -/** - * A null-coalescing operation, either `x ?? y` or `x ??= y`. - */ -class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { } From d13e5e85224e064ace57d4e2b749ce661324f20f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 29 May 2026 15:16:20 +0200 Subject: [PATCH 11/11] C#: Deprecate the operation module. --- csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll | 1 - csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll index 7f75a0bd31ff..857212f90aac 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll @@ -14,7 +14,6 @@ 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 diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll index 9e43afc856cd..19de7f20ee37 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Operation.qll @@ -1,5 +1,6 @@ /** * Provides classes for operations that also have compound assignment forms. */ +deprecated module; import Expr