Skip to content

Commit f47a77b

Browse files
authored
Merge pull request #875 from hvitved/csharp/accessor-call-revert
Approved by calumgrant
2 parents aadd5cf + b4b6fdd commit f47a77b

File tree

16 files changed

+307
-424
lines changed

16 files changed

+307
-424
lines changed

change-notes/1.20/analysis-csharp.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,4 @@
2525

2626
## Changes to QL libraries
2727

28-
* The class `AccessorCall` (and subclasses `PropertyCall`, `IndexerCall`, and `EventCall`) have been redefined, so the expressions they represent are not necessarily the accesses themselves, but rather the expressions that give rise to the accessor calls. For example, in the property assignment `x.Prop = 0`, the call to the setter for `Prop` is no longer represented by the access `x.Prop`, but instead the whole assignment. Consequently, it is no longer safe to cast directly between `AccessorCall`s and `Access`es, and the predicate `AccessorCall::getAccess()` should be used instead.
29-
3028
## Changes to the autobuilder

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -402,17 +402,14 @@ module AssignableInternal {
402402
* `a`, if any.
403403
*/
404404
cached
405-
Expr getAccessorCallValueArgument(Access a) {
406-
a.getTarget() instanceof DeclarationWithAccessors and
407-
(
408-
exists(AssignExpr ae | tupleAssignmentDefinition(ae, a) |
409-
tupleAssignmentPair(ae, a, result)
410-
)
411-
or
412-
exists(Assignment ass | a = ass.getLValue() |
413-
result = ass.getRValue() and
414-
not ass.(AssignOperation).hasExpandedAssignment()
415-
)
405+
Expr getAccessorCallValueArgument(AccessorCall ac) {
406+
exists(AssignExpr ae | tupleAssignmentDefinition(ae, ac) |
407+
tupleAssignmentPair(ae, ac, result)
408+
)
409+
or
410+
exists(Assignment ass | ac = ass.getLValue() |
411+
result = ass.getRValue() and
412+
not ass.(AssignOperation).hasExpandedAssignment()
416413
)
417414
}
418415
}

csharp/ql/src/semmle/code/csharp/Property.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ class IndexerProperty extends Property {
513513
IndexerCall getAnIndexerCall() {
514514
result = getType().(RefType).getAnIndexer().getAnAccessor().getACall() and
515515
// The qualifier of this indexer call should be a value returned from an access of this property
516-
exists(Expr qualifier | qualifier = result.getAccess().getQualifier() |
516+
exists(Expr qualifier | qualifier = result.(IndexerAccess).getQualifier() |
517517
DataFlow::localFlow(DataFlow::exprNode(this.getAnAccess()), DataFlow::exprNode(qualifier))
518518
)
519519
}

csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ private module Internal {
477477

478478
override Expr getArgument(int i) { result = getCall().getArgument(i) }
479479

480-
override Expr getQualifier() { result = getCall().getAccess().getQualifier() }
480+
override Expr getQualifier() { result = getCall().(MemberAccess).getQualifier() }
481481

482482
override Accessor getAStaticTarget() { result = getCall().getTarget() }
483483

csharp/ql/src/semmle/code/csharp/exprs/Access.qll

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,17 @@ class MemberConstantAccess extends FieldAccess {
380380
override string toString() { result = "access to constant " + this.getTarget().getName() }
381381
}
382382

383+
/**
384+
* An internal helper class to share logic between `PropertyAccess` and
385+
* `PropertyCall`.
386+
*/
387+
library class PropertyAccessExpr extends Expr, @property_access_expr {
388+
/** Gets the target of this property access. */
389+
Property getProperty() { expr_access(this, result) }
390+
391+
override string toString() { result = "access to property " + this.getProperty().getName() }
392+
}
393+
383394
/**
384395
* An access to a property, for example the access to `P` on line 5 in
385396
*
@@ -393,13 +404,8 @@ class MemberConstantAccess extends FieldAccess {
393404
* }
394405
* ```
395406
*/
396-
class PropertyAccess extends AssignableMemberAccess, @property_access_expr {
397-
/** Gets the target of this property access. */
398-
Property getProperty() { expr_access(this, result) }
399-
407+
class PropertyAccess extends AssignableMemberAccess, PropertyAccessExpr {
400408
override Property getTarget() { result = this.getProperty() }
401-
402-
override string toString() { result = "access to property " + this.getProperty().getName() }
403409
}
404410

405411
/**
@@ -509,6 +515,17 @@ class ElementRead extends ElementAccess, AssignableRead { }
509515
*/
510516
class ElementWrite extends ElementAccess, AssignableWrite { }
511517

518+
/**
519+
* An internal helper class to share logic between `IndexerAccess` and
520+
* `IndexerCall`.
521+
*/
522+
library class IndexerAccessExpr extends Expr, @indexer_access_expr {
523+
/** Gets the target of this indexer access. */
524+
Indexer getIndexer() { expr_access(this, result) }
525+
526+
override string toString() { result = "access to indexer" }
527+
}
528+
512529
/**
513530
* An access to an indexer, for example the access to `c` on line 5 in
514531
*
@@ -522,17 +539,12 @@ class ElementWrite extends ElementAccess, AssignableWrite { }
522539
* }
523540
* ```
524541
*/
525-
class IndexerAccess extends AssignableMemberAccess, ElementAccess, @indexer_access_expr {
526-
/** Gets the target of this indexer access. */
527-
Indexer getIndexer() { expr_access(this, result) }
528-
542+
class IndexerAccess extends AssignableMemberAccess, ElementAccess, IndexerAccessExpr {
529543
override Indexer getTarget() { result = this.getIndexer() }
530544

531545
override Indexer getQualifiedDeclaration() {
532546
result = ElementAccess.super.getQualifiedDeclaration()
533547
}
534-
535-
override string toString() { result = "access to indexer" }
536548
}
537549

538550
/**
@@ -588,6 +600,17 @@ class VirtualIndexerAccess extends IndexerAccess {
588600
VirtualIndexerAccess() { targetIsOverridableOrImplementable() }
589601
}
590602

603+
/**
604+
* An internal helper class to share logic between `EventAccess` and
605+
* `EventCall`.
606+
*/
607+
library class EventAccessExpr extends Expr, @event_access_expr {
608+
/** Gets the target of this event access. */
609+
Event getEvent() { expr_access(this, result) }
610+
611+
override string toString() { result = "access to event " + this.getEvent().getName() }
612+
}
613+
591614
/**
592615
* An access to an event, for example the accesses to `Click` on lines
593616
* 7 and 8 in
@@ -605,13 +628,8 @@ class VirtualIndexerAccess extends IndexerAccess {
605628
* }
606629
* ```
607630
*/
608-
class EventAccess extends AssignableMemberAccess, @event_access_expr {
609-
/** Gets the target of this event access. */
610-
Event getEvent() { expr_access(this, result) }
611-
631+
class EventAccess extends AssignableMemberAccess, EventAccessExpr {
612632
override Event getTarget() { result = getEvent() }
613-
614-
override string toString() { result = "access to event " + this.getEvent().getName() }
615633
}
616634

617635
/**

0 commit comments

Comments
 (0)