Skip to content

Commit 08547cb

Browse files
authored
Merge pull request #22205 from michaelnebel/csharp/nameofvirtualincons
C#: Allow virtual member access in `nameof` expressions in `cs/virtual-call-in-constructor`.
2 parents 3910ea4 + b52ea33 commit 08547cb

4 files changed

Lines changed: 19 additions & 12 deletions

File tree

csharp/ql/src/Bad Practices/VirtualCallInConstructorOrDestructor.ql

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ predicate virtualCallToSelfInConstructor(Expr e) {
1919
(c instanceof Constructor or c instanceof Destructor) and
2020
t = c.getDeclaringType() and
2121
virtualAccessWithThisQualifier(e, d) and
22+
not e = any(NameOfExpr ne).getAccess().getAChildExpr*() and
2223
t.getABaseType*() = d.getDeclaringType() and
2324
not t.isSealed() and
2425
not overriddenSealed(t.getABaseType*(), d)
@@ -34,17 +35,15 @@ predicate overriddenSealed(RefType t, Virtualizable d) {
3435
}
3536

3637
predicate virtualAccessWithThisQualifier(Expr e, Member d) {
37-
exists(VirtualMethodCall c |
38-
c = e and c.getTarget() = d and c.hasThisQualifier() and not c.isImplicit()
39-
)
38+
e = any(VirtualMethodCall c | c.getTarget() = d and c.hasThisQualifier() and not c.isImplicit())
4039
or
41-
exists(VirtualMethodAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
40+
e = any(VirtualMethodAccess c | c.getTarget() = d and c.hasThisQualifier())
4241
or
43-
exists(VirtualPropertyAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
42+
e = any(VirtualPropertyAccess c | c.getTarget() = d and c.hasThisQualifier())
4443
or
45-
exists(VirtualIndexerAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
44+
e = any(VirtualIndexerAccess c | c.getTarget() = d and c.hasThisQualifier())
4645
or
47-
exists(VirtualEventAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
46+
e = any(VirtualEventAccess c | c.getTarget() = d and c.hasThisQualifier())
4847
}
4948

5049
from Expr e
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `cs/virtual-call-in-constructor` has been improved. Uses of virtual members in `nameof` expressions are no longer reported, since they are not calls.

csharp/ql/test/query-tests/Bad Practices/VirtualCallInConstructorOrDestructor/VirtualCallInConstructorOrDestructor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public void f_nonvirtual() { }
1515
public void f_interface() { }
1616

1717
public virtual int p_virtual { get { return 0; } }
18+
public virtual string p_virtual_string { get { return ""; } }
1819
public virtual int p_sealed { get { return 0; } }
1920
public int p_nonvirtual { get { return 0; } }
2021

@@ -55,11 +56,14 @@ class C : B
5556
a = f_sealed; // GOOD
5657
a = f_nonvirtual; // GOOD
5758
a = f_interface; // GOOD
59+
var f_name = nameof(f_virtual); // GOOD
5860

5961
// Property access
6062
int i = p_virtual; // $ Alert // BAD
6163
i = p_sealed; // GOOD
6264
i = p_nonvirtual; // GOOD
65+
var p_name = nameof(p_virtual_string); // GOOD
66+
var p_length_name = nameof(p_virtual_string.Length); // GOOD
6367

6468
// Indexer access
6569
i = this[0]; // $ Alert // BAD
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| VirtualCallInConstructorOrDestructor.cs:45:13:45:23 | call to method f_virtual | Avoid virtual calls in a constructor or destructor. |
2-
| VirtualCallInConstructorOrDestructor.cs:54:17:54:25 | access to method f_virtual | Avoid virtual calls in a constructor or destructor. |
3-
| VirtualCallInConstructorOrDestructor.cs:60:21:60:29 | access to property p_virtual | Avoid virtual calls in a constructor or destructor. |
4-
| VirtualCallInConstructorOrDestructor.cs:65:17:65:23 | access to indexer | Avoid virtual calls in a constructor or destructor. |
5-
| VirtualCallInConstructorOrDestructor.cs:70:13:70:21 | access to event e_virtual | Avoid virtual calls in a constructor or destructor. |
1+
| VirtualCallInConstructorOrDestructor.cs:46:13:46:23 | call to method f_virtual | Avoid virtual calls in a constructor or destructor. |
2+
| VirtualCallInConstructorOrDestructor.cs:55:17:55:25 | access to method f_virtual | Avoid virtual calls in a constructor or destructor. |
3+
| VirtualCallInConstructorOrDestructor.cs:62:21:62:29 | access to property p_virtual | Avoid virtual calls in a constructor or destructor. |
4+
| VirtualCallInConstructorOrDestructor.cs:69:17:69:23 | access to indexer | Avoid virtual calls in a constructor or destructor. |
5+
| VirtualCallInConstructorOrDestructor.cs:74:13:74:21 | access to event e_virtual | Avoid virtual calls in a constructor or destructor. |

0 commit comments

Comments
 (0)