66import csharp
77private import codeql.controlflow.Cfg as CfgShared
88private import Completion
9- private import Splitting
109private import semmle.code.csharp.ExprOrStmtParent
1110private import semmle.code.csharp.commons.Compilation
1211
12+ 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+ InitializedInstanceMember ( ) {
18+ exists ( AssignExpr ae |
19+ not this .isStatic ( ) and
20+ expr_parent_top_level ( ae , _, this ) and
21+ not ae = any ( Callable c ) .getExpressionBody ( )
22+ )
23+ }
24+
25+ /** Gets the initializer expression. */
26+ AssignExpr getInitializer ( ) { expr_parent_top_level ( result , _, this ) }
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+
40+ /**
41+ * Gets the `i`th member initializer expression for object initializer method `obinit`
42+ * in compilation `comp`.
43+ */
44+ AssignExpr initializedInstanceMemberOrder ( ObjectInitMethod obinit , CompilationExt comp , int i ) {
45+ obinitInitializes ( obinit , result ) and
46+ result =
47+ rank [ i + 1 ] ( AssignExpr ae0 , Location l |
48+ obinitInitializes ( obinit , ae0 ) and
49+ l = ae0 .getLocation ( ) and
50+ getCompilation ( l .getFile ( ) ) = comp
51+ |
52+ ae0 order by l .getStartLine ( ) , l .getStartColumn ( ) , l .getFile ( ) .getAbsolutePath ( )
53+ )
54+ }
55+
56+ /**
57+ * Gets the last member initializer expression for non-static constructor `c`
58+ * in compilation `comp`.
59+ */
60+ AssignExpr lastInitializer ( ObjectInitMethod obinit , CompilationExt comp ) {
61+ exists ( int i |
62+ result = initializedInstanceMemberOrder ( obinit , comp , i ) and
63+ not exists ( initializedInstanceMemberOrder ( obinit , comp , i + 1 ) )
64+ )
65+ }
66+ }
67+
1368/** An element that defines a new CFG scope. */
1469class CfgScope extends Element , @top_level_exprorstmt_parent {
1570 CfgScope ( ) {
@@ -19,7 +74,7 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
1974 any ( Callable c |
2075 c .( Constructor ) .hasInitializer ( )
2176 or
22- InitializerSplitting :: obinitInitializes ( c , _)
77+ Initializers :: obinitInitializes ( c , _)
2378 or
2479 c .hasBody ( )
2580 )
@@ -154,7 +209,7 @@ predicate scopeFirst(CfgScope scope, AstNode first) {
154209 else first ( c .getBody ( ) , first )
155210 )
156211 or
157- first ( InitializerSplitting :: initializedInstanceMemberOrder ( scope , _, 0 ) , first )
212+ first ( Initializers :: initializedInstanceMemberOrder ( scope , _, 0 ) , first )
158213 or
159214 expr_parent_top_level_adjusted2 ( any ( Expr e | first ( e , first ) ) , _, scope ) and
160215 not scope instanceof Callable
@@ -171,7 +226,7 @@ predicate scopeLast(CfgScope scope, AstNode last, Completion c) {
171226 not callable .hasBody ( )
172227 )
173228 or
174- last ( InitializerSplitting :: lastInitializer ( scope , _) , last , c )
229+ last ( Initializers :: lastInitializer ( scope , _) , last , c )
175230 or
176231 expr_parent_top_level_adjusted2 ( any ( Expr e | last ( e , last , c ) ) , _, scope ) and
177232 not scope instanceof Callable
@@ -187,9 +242,9 @@ private class ObjectInitTree extends ControlFlowTree instanceof ObjectInitMethod
187242 final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
188243 exists ( CompilationExt comp , int i |
189244 // Flow from one member initializer to the next
190- last ( InitializerSplitting :: initializedInstanceMemberOrder ( this , comp , i ) , pred , c ) and
245+ last ( Initializers :: initializedInstanceMemberOrder ( this , comp , i ) , pred , c ) and
191246 c instanceof NormalCompletion and
192- first ( InitializerSplitting :: initializedInstanceMemberOrder ( this , comp , i + 1 ) , succ )
247+ first ( Initializers :: initializedInstanceMemberOrder ( this , comp , i + 1 ) , succ )
193248 )
194249 }
195250}
0 commit comments