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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ predicate virtualCallToSelfInConstructor(Expr e) {
(c instanceof Constructor or c instanceof Destructor) and
t = c.getDeclaringType() and
virtualAccessWithThisQualifier(e, d) and
not e = any(NameOfExpr ne).getAccess().getAChildExpr*() and
t.getABaseType*() = d.getDeclaringType() and
not t.isSealed() and
not overriddenSealed(t.getABaseType*(), d)
Expand All @@ -34,17 +35,15 @@ predicate overriddenSealed(RefType t, Virtualizable d) {
}

predicate virtualAccessWithThisQualifier(Expr e, Member d) {
exists(VirtualMethodCall c |
c = e and c.getTarget() = d and c.hasThisQualifier() and not c.isImplicit()
)
e = any(VirtualMethodCall c | c.getTarget() = d and c.hasThisQualifier() and not c.isImplicit())
or
exists(VirtualMethodAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
e = any(VirtualMethodAccess c | c.getTarget() = d and c.hasThisQualifier())
or
exists(VirtualPropertyAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
e = any(VirtualPropertyAccess c | c.getTarget() = d and c.hasThisQualifier())
or
exists(VirtualIndexerAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
e = any(VirtualIndexerAccess c | c.getTarget() = d and c.hasThisQualifier())
or
exists(VirtualEventAccess c | c = e and c.getTarget() = d and c.hasThisQualifier())
e = any(VirtualEventAccess c | c.getTarget() = d and c.hasThisQualifier())
}

from Expr e
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* 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.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public void f_nonvirtual() { }
public void f_interface() { }

public virtual int p_virtual { get { return 0; } }
public virtual string p_virtual_string { get { return ""; } }
public virtual int p_sealed { get { return 0; } }
public int p_nonvirtual { get { return 0; } }

Expand Down Expand Up @@ -55,11 +56,14 @@ class C : B
a = f_sealed; // GOOD
a = f_nonvirtual; // GOOD
a = f_interface; // GOOD
var f_name = nameof(f_virtual); // GOOD

// Property access
int i = p_virtual; // $ Alert // BAD
i = p_sealed; // GOOD
i = p_nonvirtual; // GOOD
var p_name = nameof(p_virtual_string); // GOOD
var p_length_name = nameof(p_virtual_string.Length); // GOOD

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