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
27 changes: 27 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/Callable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,22 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
ExtensionTypeExtensionMethod() { this.isInExtension() }
}

/**
* A non-static member with an initializer, for example a field `int Field = 0`.
*/
private class InitializedInstanceMember extends Member {
private AssignExpr ae;

InitializedInstanceMember() {
not this.isStatic() and
expr_parent_top_level(ae, _, this) and
not ae = getExpressionBody(_)
}

/** Gets the initializer expression. */
AssignExpr getInitializer() { result = ae }
}

/**
* An object initializer method.
*
Expand All @@ -347,6 +363,17 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
*/
class ObjectInitMethod extends Method {
ObjectInitMethod() { this.getName() = "<object initializer>" }

/**
* Holds if this object initializer method performs the initialization
* of a member via assignment `init`.
*/
predicate initializes(AssignExpr init) {
exists(InitializedInstanceMember m |
this.getDeclaringType().getAMember() = m and
init = m.getInitializer()
)
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ private module Cached {
parent*(enclosingStart(cfe), c.(Constructor).getInitializer())
or
parent*(cfe, c.(Constructor).getObjectInitializerCall())
or
parent*(cfe, any(AssignExpr init | c.(ObjectInitMethod).initializes(init)))
}

/** Holds if the enclosing statement of expression `e` is `s`. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,15 @@ private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.commons.Compilation

private module Initializers {
/**
* A non-static member with an initializer, for example a field `int Field = 0`.
*/
class InitializedInstanceMember extends Member {
private AssignExpr ae;

InitializedInstanceMember() {
not this.isStatic() and
expr_parent_top_level(ae, _, this) and
not ae = any(Callable c).getExpressionBody()
}

/** Gets the initializer expression. */
AssignExpr getInitializer() { result = ae }
}

/**
* Holds if `obinit` is an object initializer method that performs the initialization
* of a member via assignment `init`.
*/
predicate obinitInitializes(ObjectInitMethod obinit, AssignExpr init) {
exists(InitializedInstanceMember m |
obinit.getDeclaringType().getAMember() = m and
init = m.getInitializer()
)
}

/**
* Gets the `i`th member initializer expression for object initializer method `obinit`
* in compilation `comp`.
*/
AssignExpr initializedInstanceMemberOrder(ObjectInitMethod obinit, CompilationExt comp, int i) {
obinitInitializes(obinit, result) and
obinit.initializes(result) and
result =
rank[i + 1](AssignExpr ae0, Location l |
obinitInitializes(obinit, ae0) and
obinit.initializes(ae0) and
l = ae0.getLocation() and
getCompilation(l.getFile()) = comp
|
Expand Down Expand Up @@ -74,7 +47,7 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
any(Callable c |
c.(Constructor).hasInitializer()
or
Initializers::obinitInitializes(c, _)
c.(ObjectInitMethod).initializes(_)
or
c.hasBody()
)
Expand Down
1 change: 1 addition & 0 deletions csharp/ql/test/library-tests/dispatch/CallGraph.expected
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:172:21:172:33 | MethodWithOut |
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:177:21:177:34 | MethodWithOut2 |
| ExactCallable.cs:182:21:182:22 | M1 | ExactCallable.cs:187:21:187:22 | M2 |
| TypeFlow.cs:3:7:3:14 | <object initializer> | TypeFlow.cs:22:20:22:22 | set_Prop |
| TypeFlow.cs:5:5:5:12 | TypeFlow | TypeFlow.cs:24:10:24:12 | Run |
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:12:29:12:34 | Method |
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:17:30:17:35 | Method |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ gvn
| StructuralComparison.cs:3:14:3:18 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:3:14:3:18 | {...} | (kind:Stmt(1)) |
| StructuralComparison.cs:5:26:5:26 | access to field x | (kind:Expr(16),true,x) |
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12)) |
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:5:26:5:30 | ... = ... | ((kind:Expr(16),true,x) :: (0 :: (kind:Expr(63)))) |
| StructuralComparison.cs:5:30:5:30 | 0 | 0 |
| StructuralComparison.cs:6:26:6:26 | access to field y | (kind:Expr(16),true,y) |
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12)) |
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:6:26:6:30 | ... = ... | ((kind:Expr(16),true,y) :: (1 :: (kind:Expr(63)))) |
| StructuralComparison.cs:6:30:6:30 | 1 | 1 |
| StructuralComparison.cs:8:24:8:24 | 0 | 0 |
Expand Down
Loading