Skip to content

Commit d4a0846

Browse files
authored
Merge pull request #21490 from aschackmull/csharp/enclosing-obinit
C#: Add ObjectInitMethod as enclosing callable for the instance initializers.
2 parents 8e19b05 + af63e63 commit d4a0846

File tree

5 files changed

+35
-32
lines changed

5 files changed

+35
-32
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,22 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
336336
ExtensionTypeExtensionMethod() { this.isInExtension() }
337337
}
338338

339+
/**
340+
* A non-static member with an initializer, for example a field `int Field = 0`.
341+
*/
342+
private class InitializedInstanceMember extends Member {
343+
private AssignExpr ae;
344+
345+
InitializedInstanceMember() {
346+
not this.isStatic() and
347+
expr_parent_top_level(ae, _, this) and
348+
not ae = getExpressionBody(_)
349+
}
350+
351+
/** Gets the initializer expression. */
352+
AssignExpr getInitializer() { result = ae }
353+
}
354+
339355
/**
340356
* An object initializer method.
341357
*
@@ -347,6 +363,17 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
347363
*/
348364
class ObjectInitMethod extends Method {
349365
ObjectInitMethod() { this.getName() = "<object initializer>" }
366+
367+
/**
368+
* Holds if this object initializer method performs the initialization
369+
* of a member via assignment `init`.
370+
*/
371+
predicate initializes(AssignExpr init) {
372+
exists(InitializedInstanceMember m |
373+
this.getDeclaringType().getAMember() = m and
374+
init = m.getInitializer()
375+
)
376+
}
350377
}
351378

352379
/**

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ private module Cached {
214214
parent*(enclosingStart(cfe), c.(Constructor).getInitializer())
215215
or
216216
parent*(cfe, c.(Constructor).getObjectInitializerCall())
217+
or
218+
parent*(cfe, any(AssignExpr init | c.(ObjectInitMethod).initializes(init)))
217219
}
218220

219221
/** Holds if the enclosing statement of expression `e` is `s`. */

csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,15 @@ private import semmle.code.csharp.ExprOrStmtParent
1010
private import semmle.code.csharp.commons.Compilation
1111

1212
private module Initializers {
13-
/**
14-
* A non-static member with an initializer, for example a field `int Field = 0`.
15-
*/
16-
class InitializedInstanceMember extends Member {
17-
private AssignExpr ae;
18-
19-
InitializedInstanceMember() {
20-
not this.isStatic() and
21-
expr_parent_top_level(ae, _, this) and
22-
not ae = any(Callable c).getExpressionBody()
23-
}
24-
25-
/** Gets the initializer expression. */
26-
AssignExpr getInitializer() { result = ae }
27-
}
28-
29-
/**
30-
* Holds if `obinit` is an object initializer method that performs the initialization
31-
* of a member via assignment `init`.
32-
*/
33-
predicate obinitInitializes(ObjectInitMethod obinit, AssignExpr init) {
34-
exists(InitializedInstanceMember m |
35-
obinit.getDeclaringType().getAMember() = m and
36-
init = m.getInitializer()
37-
)
38-
}
39-
4013
/**
4114
* Gets the `i`th member initializer expression for object initializer method `obinit`
4215
* in compilation `comp`.
4316
*/
4417
AssignExpr initializedInstanceMemberOrder(ObjectInitMethod obinit, CompilationExt comp, int i) {
45-
obinitInitializes(obinit, result) and
18+
obinit.initializes(result) and
4619
result =
4720
rank[i + 1](AssignExpr ae0, Location l |
48-
obinitInitializes(obinit, ae0) and
21+
obinit.initializes(ae0) and
4922
l = ae0.getLocation() and
5023
getCompilation(l.getFile()) = comp
5124
|
@@ -74,7 +47,7 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
7447
any(Callable c |
7548
c.(Constructor).hasInitializer()
7649
or
77-
Initializers::obinitInitializes(c, _)
50+
c.(ObjectInitMethod).initializes(_)
7851
or
7952
c.hasBody()
8053
)

csharp/ql/test/library-tests/dispatch/CallGraph.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:172:21:172:33 | MethodWithOut |
2525
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:177:21:177:34 | MethodWithOut2 |
2626
| ExactCallable.cs:182:21:182:22 | M1 | ExactCallable.cs:187:21:187:22 | M2 |
27+
| TypeFlow.cs:3:7:3:14 | <object initializer> | TypeFlow.cs:22:20:22:22 | set_Prop |
2728
| TypeFlow.cs:5:5:5:12 | TypeFlow | TypeFlow.cs:24:10:24:12 | Run |
2829
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:12:29:12:34 | Method |
2930
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:17:30:17:35 | Method |

csharp/ql/test/library-tests/structuralcomparison/structuralComparison.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ gvn
5656
| StructuralComparison.cs:3:14:3:18 | this access | (kind:Expr(12),false,Class) |
5757
| StructuralComparison.cs:3:14:3:18 | {...} | (kind:Stmt(1)) |
5858
| StructuralComparison.cs:5:26:5:26 | access to field x | (kind:Expr(16),true,x) |
59-
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12)) |
59+
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12),false,Class) |
6060
| StructuralComparison.cs:5:26:5:30 | ... = ... | ((kind:Expr(16),true,x) :: (0 :: (kind:Expr(63)))) |
6161
| StructuralComparison.cs:5:30:5:30 | 0 | 0 |
6262
| StructuralComparison.cs:6:26:6:26 | access to field y | (kind:Expr(16),true,y) |
63-
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12)) |
63+
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12),false,Class) |
6464
| StructuralComparison.cs:6:26:6:30 | ... = ... | ((kind:Expr(16),true,y) :: (1 :: (kind:Expr(63)))) |
6565
| StructuralComparison.cs:6:30:6:30 | 1 | 1 |
6666
| StructuralComparison.cs:8:24:8:24 | 0 | 0 |

0 commit comments

Comments
 (0)