Skip to content

Commit 40ce2ac

Browse files
committed
C#: Introduce a new kind of assignable definitions for compound assignments (those that was previously covered by expanded assignments).
1 parent e0919f1 commit 40ce2ac

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

csharp/ql/lib/semmle/code/csharp/Assignable.qll

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class AssignableRead extends AssignableAccess {
7878
this.isRefArgument()
7979
or
8080
this = any(AssignableDefinitions::AddressOfDefinition def).getTargetAccess()
81+
or
82+
this = any(AssignableDefinitions::AssignOperationDefinition def).getTargetAccess()
8183
) and
8284
not nameOfChild(_, this)
8385
}
@@ -271,6 +273,8 @@ module AssignableInternal {
271273
def = TAddressOfDefinition(result)
272274
or
273275
def = TPatternDefinition(result)
276+
or
277+
def = TAssignOperationDefinition(result)
274278
}
275279

276280
/** A local variable declaration at the top-level of a pattern. */
@@ -286,7 +290,11 @@ module AssignableInternal {
286290
private module Cached {
287291
cached
288292
newtype TAssignableDefinition =
289-
TAssignmentDefinition(Assignment a) { not a.getLValue() instanceof TupleExpr } or
293+
TAssignmentDefinition(Assignment a) {
294+
not a.getLValue() instanceof TupleExpr and
295+
not a instanceof AssignCallOperation and
296+
not a instanceof AssignCoalesceExpr
297+
} or
290298
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
291299
TOutRefDefinition(AssignableAccess aa) {
292300
aa.isOutArgument()
@@ -309,7 +317,11 @@ module AssignableInternal {
309317
)
310318
} or
311319
TAddressOfDefinition(AddressOfExpr aoe) or
312-
TPatternDefinition(TopLevelPatternDecl tlpd)
320+
TPatternDefinition(TopLevelPatternDecl tlpd) or
321+
TAssignOperationDefinition(AssignOperation ao) {
322+
ao instanceof AssignCallOperation or
323+
ao instanceof AssignCoalesceExpr
324+
}
313325

314326
/**
315327
* Gets the source expression assigned in tuple definition `def`, if any.
@@ -355,6 +367,8 @@ module AssignableInternal {
355367
def = TMutationDefinition(any(MutatorOperation mo | mo.getOperand() = result))
356368
or
357369
def = TAddressOfDefinition(any(AddressOfExpr aoe | aoe.getOperand() = result))
370+
or
371+
def = TAssignOperationDefinition(any(AssignOperation ao | ao.getLeftOperand() = result))
358372
}
359373

360374
/**
@@ -369,8 +383,10 @@ module AssignableInternal {
369383
or
370384
exists(Assignment ass | ac = ass.getLValue() |
371385
result = ass.getRValue() and
372-
not ass.(AssignOperation).hasExpandedAssignment()
386+
not ass instanceof AssignOperation
373387
)
388+
or
389+
exists(AssignOperation ao | ac = ao.getLeftOperand() | result = ao)
374390
}
375391
}
376392

@@ -388,8 +404,9 @@ private import AssignableInternal
388404
* a mutation update (`AssignableDefinitions::MutationDefinition`), a local variable
389405
* declaration without an initializer (`AssignableDefinitions::LocalVariableDefinition`),
390406
* an implicit parameter definition (`AssignableDefinitions::ImplicitParameterDefinition`),
391-
* an address-of definition (`AssignableDefinitions::AddressOfDefinition`), or a pattern
392-
* definition (`AssignableDefinitions::PatternDefinition`).
407+
* an address-of definition (`AssignableDefinitions::AddressOfDefinition`), a pattern
408+
* definition (`AssignableDefinitions::PatternDefinition`), or a compound assignment
409+
* operation definition (`AssignableDefinitions::AssignOperationDefinition`)
393410
*/
394411
class AssignableDefinition extends TAssignableDefinition {
395412
/**
@@ -511,7 +528,7 @@ module AssignableDefinitions {
511528

512529
override Expr getSource() {
513530
result = a.getRValue() and
514-
not a instanceof AssignOperation
531+
not a instanceof AddOrRemoveEventExpr
515532
}
516533

517534
override string toString() { result = a.toString() }
@@ -735,4 +752,17 @@ module AssignableDefinitions {
735752
/** Gets the assignable (field or property) being initialized. */
736753
Assignable getAssignable() { result = fieldOrProp }
737754
}
755+
756+
/**
757+
* A definition by a compound assignment operation, for example `x += y`.
758+
*/
759+
class AssignOperationDefinition extends AssignableDefinition, TAssignOperationDefinition {
760+
AssignOperation ao;
761+
762+
AssignOperationDefinition() { this = TAssignOperationDefinition(ao) }
763+
764+
override Expr getSource() { result = ao }
765+
766+
override string toString() { result = ao.toString() }
767+
}
738768
}

0 commit comments

Comments
 (0)