Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion csharp/ql/lib/Linq/Helpers.qll
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ predicate missedAllOpportunity(ForeachStmtGenericEnumerable fes) {
// The then case of the if assigns false to something and breaks out of the loop.
exists(Assignment a, BoolLiteral bl |
a = is.getThen().getAChild*() and
bl = a.getRValue() and
bl = a.getRightOperand() and
bl.toString() = "false"
) and
is.getThen().getAChild*() instanceof BreakStmt
Expand Down
4 changes: 4 additions & 0 deletions csharp/ql/lib/change-notes/2026-04-01-getlrvalue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: deprecated
---
* The predicates `get[L|R]Value` in the class `Assignment` have been deprecated. Use `get[Left|Right]Operand` instead.
Copy link

Copilot AI

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change note uses shorthand get[L|R]Value / get[Left|Right]Operand, which can be read as a literal identifier (including |) and is ambiguous. Consider spelling these out explicitly as getLValue/getRValue and getLeftOperand/getRightOperand for clarity.

Suggested change
* The predicates `get[L|R]Value` in the class `Assignment` have been deprecated. Use `get[Left|Right]Operand` instead.
* The predicates `getLValue` and `getRValue` in the class `Assignment` have been deprecated. Use `getLeftOperand` and `getRightOperand` instead.

Copilot uses AI. Check for mistakes.
2 changes: 1 addition & 1 deletion csharp/ql/lib/definitions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private class MethodUse extends Use, QualifiableExpr {
private class AccessUse extends Access, Use {
AccessUse() {
not this.getTarget().(Parameter).getCallable() instanceof Accessor and
not this = any(LocalVariableDeclAndInitExpr d).getLValue() and
not this = any(LocalVariableDeclAndInitExpr d).getLeftOperand() and
not this.isImplicit() and
not this instanceof MethodAccess and // handled by `MethodUse`
not this instanceof TypeAccess and // handled by `TypeMentionUse`
Expand Down
16 changes: 8 additions & 8 deletions csharp/ql/lib/semmle/code/csharp/Assignable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private class RefArg extends AssignableAccess {
module AssignableInternal {
private predicate tupleAssignmentDefinition(AssignExpr ae, Expr leaf) {
exists(TupleExpr te |
ae.getLValue() = te and
ae.getLeftOperand() = te and
te.getAnArgument+() = leaf and
// `leaf` is either an assignable access or a local variable declaration
not leaf instanceof TupleExpr
Expand All @@ -249,8 +249,8 @@ module AssignableInternal {
*/
private predicate tupleAssignmentPair(AssignExpr ae, Expr left, Expr right) {
tupleAssignmentDefinition(ae, _) and
left = ae.getLValue() and
right = ae.getRValue()
left = ae.getLeftOperand() and
right = ae.getRightOperand()
or
exists(TupleExpr l, TupleExpr r, int i | tupleAssignmentPair(ae, l, r) |
left = l.getArgument(i) and
Expand Down Expand Up @@ -291,7 +291,7 @@ module AssignableInternal {
cached
newtype TAssignableDefinition =
TAssignmentDefinition(Assignment a) {
not a.getLValue() instanceof TupleExpr and
not a.getLeftOperand() instanceof TupleExpr and
not a instanceof AssignCallOperation and
not a instanceof AssignCoalesceExpr
} or
Expand Down Expand Up @@ -358,7 +358,7 @@ module AssignableInternal {
// Not defined by dispatch in order to avoid too conservative negative recursion error
cached
AssignableAccess getTargetAccess(AssignableDefinition def) {
def = TAssignmentDefinition(any(Assignment a | a.getLValue() = result))
def = TAssignmentDefinition(any(Assignment a | a.getLeftOperand() = result))
or
def = TTupleAssignmentDefinition(_, result)
or
Expand All @@ -381,8 +381,8 @@ module AssignableInternal {
tupleAssignmentPair(ae, ac, result)
)
or
exists(Assignment ass | ac = ass.getLValue() |
result = ass.getRValue() and
exists(Assignment ass | ac = ass.getLeftOperand() |
result = ass.getRightOperand() and
not ass instanceof AssignOperation
)
or
Expand Down Expand Up @@ -527,7 +527,7 @@ module AssignableDefinitions {
Assignment getAssignment() { result = a }

override Expr getSource() {
result = a.getRValue() and
result = a.getRightOperand() and
not a instanceof AddOrRemoveEventExpr
}

Expand Down
4 changes: 2 additions & 2 deletions csharp/ql/lib/semmle/code/csharp/PrintAst.qll
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,10 @@ final class AssignmentNode extends ControlFlowElementNode {
result.(TypeMentionNode).getTarget() = controlFlowElement
or
childIndex = 0 and
result.(ElementNode).getElement() = assignment.getLValue()
result.(ElementNode).getElement() = assignment.getLeftOperand()
or
childIndex = 1 and
result.(ElementNode).getElement() = assignment.getRValue()
result.(ElementNode).getElement() = assignment.getRightOperand()
}
}

Expand Down
4 changes: 2 additions & 2 deletions csharp/ql/lib/semmle/code/csharp/Property.qll
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ class Setter extends Accessor, @setter {
exists(AssignExpr assign |
this.getStatementBody().getNumberOfStmts() = 1 and
assign.getParent() = this.getStatementBody().getAChild() and
assign.getLValue() = result.getAnAccess() and
assign.getRValue() = accessToValue()
assign.getLeftOperand() = result.getAnAccess() and
assign.getRightOperand() = accessToValue()
)
}

Expand Down
6 changes: 3 additions & 3 deletions csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private module GuardsInput implements
IdExpr() { this instanceof AssignExpr or this instanceof CastExpr }

Expr getEqualChildExpr() {
result = this.(AssignExpr).getRValue()
result = this.(AssignExpr).getRightOperand()
or
result = this.(CastExpr).getExpr()
}
Expand Down Expand Up @@ -836,7 +836,7 @@ module Internal {

/** Holds if expression `e2` is a `null` value whenever `e1` is. */
predicate nullValueImpliedUnary(Expr e1, Expr e2) {
e1 = e2.(AssignExpr).getRValue()
e1 = e2.(AssignExpr).getRightOperand()
or
e1 = e2.(Cast).getExpr()
or
Expand Down Expand Up @@ -923,7 +923,7 @@ module Internal {
/** Holds if expression `e2` is a non-`null` value whenever `e1` is. */
predicate nonNullValueImpliedUnary(Expr e1, Expr e2) {
e1 = e2.(CastExpr).getExpr() or
e1 = e2.(AssignExpr).getRValue() or
e1 = e2.(AssignExpr).getRightOperand() or
e1 = e2.(NullCoalescingOperation).getAnOperand()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ module Expressions {
// ```
// need special treatment, because the accesses `[0]`, `[1]`, and `[2]`
// have no qualifier.
this = any(MemberInitializer mi).getLValue()
this = any(MemberInitializer mi).getLeftOperand()
) and
not exists(AssignableDefinitions::OutRefDefinition def | def.getTargetAccess() = this)
}
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private Expr maybeNullExpr(Expr reason) {
or
result instanceof AsExpr and reason = result
or
result.(AssignExpr).getRValue() = maybeNullExpr(reason)
result.(AssignExpr).getRightOperand() = maybeNullExpr(reason)
or
result.(CastExpr).getExpr() = maybeNullExpr(reason)
or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ module LocalFlow {
e2 =
any(AssignExpr ae |
ae.getParent() = any(ControlFlowElement cfe | not cfe instanceof ExprStmt) and
e1 = ae.getRValue()
e1 = ae.getRightOperand()
)
or
e1 = e2.(ObjectCreation).getInitializer()
Expand All @@ -554,7 +554,7 @@ module LocalFlow {
e2 = we
)
or
exists(AssignExpr ae | ae.getLValue().(TupleExpr) = e2 and ae.getRValue() = e1)
exists(AssignExpr ae | ae.getLeftOperand().(TupleExpr) = e2 and ae.getRightOperand() = e1)
or
exists(ControlFlowElement cfe | cfe = e2.(TupleExpr).(PatternExpr).getPatternMatch() |
cfe.(IsExpr).getExpr() = e1
Expand Down Expand Up @@ -795,7 +795,7 @@ private predicate fieldOrPropertyStore(ContentSet c, Expr src, Expr q, boolean p
q = we and
mi = we.getInitializer().getAMemberInitializer() and
f = mi.getInitializedMember() and
src = mi.getRValue() and
src = mi.getRightOperand() and
postUpdate = false
)
or
Expand All @@ -804,7 +804,7 @@ private predicate fieldOrPropertyStore(ContentSet c, Expr src, Expr q, boolean p
mi = q.(ObjectInitializer).getAMemberInitializer() and
q.getParent() instanceof ObjectCreation and
f = mi.getInitializedMember() and
src = mi.getRValue() and
src = mi.getRightOperand() and
postUpdate = false
)
or
Expand Down Expand Up @@ -879,8 +879,8 @@ private predicate arrayStore(Expr src, Expr a, boolean postUpdate) {
// Member initializer, `new C { Array = { [i] = src } }`
exists(MemberInitializer mi |
mi = a.(ObjectInitializer).getAMemberInitializer() and
mi.getLValue() instanceof ArrayAccess and
mi.getRValue() = src and
mi.getLeftOperand() instanceof ArrayAccess and
mi.getRightOperand() = src and
postUpdate = false
)
}
Expand Down Expand Up @@ -2582,7 +2582,7 @@ module PostUpdateNodes {
call.getExpr() = init.(CollectionInitializer).getAnElementInitializer()
or
// E.g. `new Dictionary<int, string>() { [0] = "a", [1] = "b" }`
call.getExpr() = init.(ObjectInitializer).getAMemberInitializer().getLValue()
call.getExpr() = init.(ObjectInitializer).getAMemberInitializer().getLeftOperand()
)
}

Expand Down Expand Up @@ -2795,7 +2795,7 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
preservesValue = true
or
exists(AddEventExpr aee |
nodeFrom.asExpr() = aee.getRValue() and
nodeFrom.asExpr() = aee.getRightOperand() and
nodeTo.asExpr().(EventRead).getTarget() = aee.getTarget() and
preservesValue = false
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ private module CallGraph {
pred = succ.(DelegateCreation).getArgument()
or
exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() |
pred = ae.getRValue()
pred = ae.getRightOperand()
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private module Impl {
/** Holds if SSA definition `def` equals `e + delta`. */
predicate ssaUpdateStep(ExplicitDefinition def, ExprNode e, int delta) {
exists(ControlFlow::Node cfn | cfn = def.getControlFlowNode() |
e = cfn.(ExprNode::Assignment).getRValue() and
e = cfn.(ExprNode::Assignment).getRightOperand() and
delta = 0 and
not cfn instanceof ExprNode::AssignOperation
or
Expand All @@ -39,7 +39,7 @@ private module Impl {

/** Holds if `e1 + delta` equals `e2`. */
predicate valueFlowStep(ExprNode e2, ExprNode e1, int delta) {
e2.(ExprNode::AssignExpr).getRValue() = e1 and delta = 0
e2.(ExprNode::AssignExpr).getRightOperand() = e1 and delta = 0
or
e2.(ExprNode::UnaryPlusExpr).getOperand() = e1 and delta = 0
or
Expand Down Expand Up @@ -207,13 +207,13 @@ module ExprNode {
override CS::Assignment e;

/** Gets the left operand of this assignment. */
ExprNode getLValue() {
result = unique(ExprNode res | hasChild(e, e.getLValue(), this, res) | res)
ExprNode getLeftOperand() {
result = unique(ExprNode res | hasChild(e, e.getLeftOperand(), this, res) | res)
}

/** Gets the right operand of this assignment. */
ExprNode getRValue() {
result = unique(ExprNode res | hasChild(e, e.getRValue(), this, res) | res)
ExprNode getRightOperand() {
result = unique(ExprNode res | hasChild(e, e.getRightOperand(), this, res) | res)
}
}

Expand All @@ -225,6 +225,10 @@ module ExprNode {
/** A compound assignment operation. */
class AssignOperation extends Assignment, BinaryOperation {
override CS::AssignOperation e;

override ExprNode getLeftOperand() { result = Assignment.super.getLeftOperand() }

override ExprNode getRightOperand() { result = Assignment.super.getRightOperand() }
}

/** A unary operation. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ private module Impl {
/** Returned an expression that is assigned to `f`. */
Copy link

Copilot AI

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment grammar: Returned an expression that is assigned to f. should be Returns an expression that is assigned to f.

Suggested change
/** Returned an expression that is assigned to `f`. */
/** Returns an expression that is assigned to `f`. */

Copilot uses AI. Check for mistakes.
ExprNode getAssignedValueToField(Field f) {
result.getExpr() in [
f.getAnAssignedValue(), any(AssignOperation a | a.getLValue() = f.getAnAccess())
f.getAnAssignedValue(), any(AssignOperation a | a.getLeftOperand() = f.getAnAccess())
]
}

Expand Down Expand Up @@ -231,7 +231,7 @@ private module Impl {
/** Returns a sub expression of `e` for expression types where the sign depends on the child. */
ExprNode getASubExprWithSameSign(ExprNode e) {
exists(Expr e_, Expr child | hasChild(e_, child, e, result) |
child = e_.(AssignExpr).getRValue() or
child = e_.(AssignExpr).getRightOperand() or
child = e_.(UnaryPlusExpr).getOperand() or
child = e_.(PostIncrExpr).getOperand() or
child = e_.(PostDecrExpr).getOperand() or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ ExprNode ssaRead(Definition v, int delta) {
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::Assignment) = result and delta = 0
or
result.(ExprNode::AssignExpr).getRValue() = ssaRead(v, delta)
result.(ExprNode::AssignExpr).getRightOperand() = ssaRead(v, delta)
}
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1348,7 +1348,7 @@ private module Internal {
any(DynamicMemberAccess dma | this = TDispatchDynamicEventAccess(_, dma, _)).getQualifier()
}

override Expr getArgument(int i) { i = 0 and result = this.getCall().getRValue() }
override Expr getArgument(int i) { i = 0 and result = this.getCall().getRightOperand() }
}

/** A call to a constructor using dynamic types. */
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/exprs/Access.qll
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class BaseAccess extends Access, @base_access_expr {
class MemberAccess extends Access, QualifiableExpr, @member_access_expr {
override predicate hasImplicitThisQualifier() {
QualifiableExpr.super.hasImplicitThisQualifier() and
not exists(MemberInitializer mi | mi.getLValue() = this)
not exists(MemberInitializer mi | mi.getLeftOperand() = this)
}

override Member getQualifiedDeclaration() { result = this.getTarget() }
Expand Down
32 changes: 24 additions & 8 deletions csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ class Assignment extends BinaryOperation, @assign_expr {
expr_parent(_, 1, this)
}

/** Gets the left operand of this assignment. */
Expr getLValue() { result = this.getLeftOperand() }
/**
* DEPRECATED: Use `getLeftOperand` instead.
*
* Gets the left operand of this assignment.
*/
deprecated Expr getLValue() { result = this.getLeftOperand() }

/** Gets the right operand of this assignment. */
Expr getRValue() { result = this.getRightOperand() }
/**
* DEPRECATED: Use `getRightOperand` instead.
*
* Gets the right operand of this assignment.
*/
deprecated Expr getRValue() { result = this.getRightOperand() }

/** Gets the variable being assigned to, if any. */
Variable getTargetVariable() { result.getAnAccess() = this.getLValue() }
Variable getTargetVariable() { result.getAnAccess() = this.getLeftOperand() }

override string getOperator() { none() }
}
Expand All @@ -40,7 +48,12 @@ class LocalVariableDeclAndInitExpr extends LocalVariableDeclExpr, Assignment {

override LocalVariable getTargetVariable() { result = this.getVariable() }

override LocalVariableAccess getLValue() { result = Assignment.super.getLValue() }
/**
* DEPRECATED: Use `getLeftOperand` instead.
*/
deprecated override LocalVariableAccess getLValue() { result = this.getLeftOperand() }

override LocalVariableAccess getLeftOperand() { result = Assignment.super.getLeftOperand() }

override string toString() { result = LocalVariableDeclExpr.super.toString() + " = ..." }

Expand Down Expand Up @@ -223,9 +236,12 @@ deprecated class AssignUnsighedRightShiftExpr = AssignUnsignedRightShiftExpr;
*/
class AddOrRemoveEventExpr extends AssignOperation, @assign_event_expr {
/** Gets the event targeted by this event assignment. */
Event getTarget() { result = this.getLValue().getTarget() }
Event getTarget() { result = this.getLeftOperand().getTarget() }

override EventAccess getLValue() { result = this.getChild(0) }
/**
* DEPRECATED: Use `getLeftOperand` instead.
*/
deprecated override EventAccess getLValue() { result = this.getLeftOperand() }

override EventAccess getLeftOperand() { result = this.getChild(0) }
}
Expand Down
6 changes: 3 additions & 3 deletions csharp/ql/lib/semmle/code/csharp/exprs/Call.qll
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ class EventCall extends AccessorCall, EventAccessExpr {
override EventAccessor getTarget() {
exists(Event e, AddOrRemoveEventExpr aoree |
e = this.getEvent() and
aoree.getLValue() = this
aoree.getLeftOperand() = this
|
aoree instanceof AddEventExpr and result = e.getAddEventAccessor()
or
Expand All @@ -784,8 +784,8 @@ class EventCall extends AccessorCall, EventAccessExpr {
override Expr getArgument(int i) {
i = 0 and
exists(AddOrRemoveEventExpr aoree |
aoree.getLValue() = this and
result = aoree.getRValue()
aoree.getLeftOperand() = this and
result = aoree.getRightOperand()
)
}

Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class MemberInitializer extends AssignExpr {
MemberInitializer() { this.getParent() instanceof ObjectInitializer }

/** Gets the initialized member. */
Member getInitializedMember() { result.getAnAccess() = this.getLValue() }
Member getInitializedMember() { result.getAnAccess() = this.getLeftOperand() }

override string getAPrimaryQlClass() { result = "MemberInitializer" }
}
Expand Down
Loading
Loading