Skip to content

Commit 977ff4f

Browse files
committed
C#: Use the first getter/setter when calling a property (override can apply to only a getter or a setter).
1 parent 0ceeace commit 977ff4f

2 files changed

Lines changed: 32 additions & 20 deletions

File tree

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,34 @@ class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelE
5757
/** Gets the `set` accessor of this declaration, if any. */
5858
Setter getSetter() { result = this.getAnAccessor() }
5959

60+
/** Gets the target `get` accessor of this declaration, if any. */
61+
private Getter getFirstGetter() {
62+
if exists(this.getGetter())
63+
then result = this.getGetter()
64+
else result = this.getOverridee().getFirstGetter()
65+
}
66+
67+
/** Gets the target accessor of this declaration when used in a read context, if any. */
68+
Accessor getReadTarget() { result = this.getFirstGetter() }
69+
70+
/** Gets the target `set` accessor of this declaration, if any. */
71+
private Setter getFirstSetter() {
72+
if exists(this.getSetter())
73+
then result = this.getSetter()
74+
else result = this.getOverridee().getFirstSetter()
75+
}
76+
77+
/** Gets the target accessor of this declaration when used in a write context, if any. */
78+
Accessor getWriteTarget() {
79+
result = this.getFirstSetter()
80+
or
81+
result =
82+
any(Getter g |
83+
g = this.getFirstGetter() and
84+
g.getAnnotatedReturnType().isRef()
85+
)
86+
}
87+
6088
override DeclarationWithGetSetAccessors getOverridee() {
6189
result = DeclarationWithAccessors.super.getOverridee()
6290
}

csharp/ql/lib/semmle/code/csharp/exprs/Call.qll

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -762,20 +762,12 @@ class AccessorCall extends Call, QualifiableExpr, @call_access_expr {
762762
*/
763763
class PropertyCall extends AccessorCall, PropertyAccessExpr {
764764
override Accessor getReadTarget() {
765-
this instanceof AssignableRead and result = this.getProperty().getGetter()
765+
this instanceof AssignableRead and result = this.getProperty().getReadTarget()
766766
}
767767

768768
override Accessor getWriteTarget() {
769769
this instanceof AssignableWrite and
770-
exists(Property p | p = this.getProperty() |
771-
result = p.getSetter()
772-
or
773-
result =
774-
any(Getter g |
775-
g = p.getGetter() and
776-
g.getAnnotatedReturnType().isRef()
777-
)
778-
)
770+
result = this.getProperty().getWriteTarget()
779771
}
780772

781773
override Expr getArgument(int i) {
@@ -806,20 +798,12 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr {
806798
*/
807799
class IndexerCall extends AccessorCall, IndexerAccessExpr {
808800
override Accessor getReadTarget() {
809-
this instanceof AssignableRead and result = this.getIndexer().getGetter()
801+
this instanceof AssignableRead and result = this.getIndexer().getReadTarget()
810802
}
811803

812804
override Accessor getWriteTarget() {
813805
this instanceof AssignableWrite and
814-
exists(Indexer i | i = this.getIndexer() |
815-
result = i.getSetter()
816-
or
817-
result =
818-
any(Getter g |
819-
g = i.getGetter() and
820-
g.getAnnotatedReturnType().isRef()
821-
)
822-
)
806+
result = this.getIndexer().getWriteTarget()
823807
}
824808

825809
override Expr getArgument(int i) {

0 commit comments

Comments
 (0)