@@ -21,9 +21,11 @@ private import semmle.code.csharp.frameworks.system.threading.Tasks
21
21
22
22
abstract class NodeImpl extends Node {
23
23
/** Do not call: use `getEnclosingCallable()` instead. */
24
+ cached
24
25
abstract DataFlowCallable getEnclosingCallableImpl ( ) ;
25
26
26
27
/** Do not call: use `getType()` instead. */
28
+ cached
27
29
abstract DotNet:: Type getTypeImpl ( ) ;
28
30
29
31
/** Gets the type of this node used for type pruning. */
@@ -39,27 +41,39 @@ abstract class NodeImpl extends Node {
39
41
}
40
42
41
43
/** Do not call: use `getControlFlowNode()` instead. */
44
+ cached
42
45
abstract ControlFlow:: Node getControlFlowNodeImpl ( ) ;
43
46
44
47
/** Do not call: use `getLocation()` instead. */
48
+ cached
45
49
abstract Location getLocationImpl ( ) ;
46
50
47
51
/** Do not call: use `toString()` instead. */
52
+ cached
48
53
abstract string toStringImpl ( ) ;
49
54
}
50
55
51
56
private class ExprNodeImpl extends ExprNode , NodeImpl {
52
57
override DataFlowCallable getEnclosingCallableImpl ( ) {
58
+ Stages:: DataFlowStage:: forceCachingInSameStage ( ) and
53
59
result = this .getExpr ( ) .getEnclosingCallable ( )
54
60
}
55
61
56
- override DotNet:: Type getTypeImpl ( ) { result = this .getExpr ( ) .getType ( ) }
62
+ override DotNet:: Type getTypeImpl ( ) {
63
+ Stages:: DataFlowStage:: forceCachingInSameStage ( ) and
64
+ result = this .getExpr ( ) .getType ( )
65
+ }
57
66
58
- override ControlFlow:: Nodes:: ElementNode getControlFlowNodeImpl ( ) { this = TExprNode ( result ) }
67
+ override ControlFlow:: Nodes:: ElementNode getControlFlowNodeImpl ( ) {
68
+ Stages:: DataFlowStage:: forceCachingInSameStage ( ) and this = TExprNode ( result )
69
+ }
59
70
60
- override Location getLocationImpl ( ) { result = this .getExpr ( ) .getLocation ( ) }
71
+ override Location getLocationImpl ( ) {
72
+ Stages:: DataFlowStage:: forceCachingInSameStage ( ) and result = this .getExpr ( ) .getLocation ( )
73
+ }
61
74
62
75
override string toStringImpl ( ) {
76
+ Stages:: DataFlowStage:: forceCachingInSameStage ( ) and
63
77
result = this .getControlFlowNode ( ) .toString ( )
64
78
or
65
79
exists ( CIL:: Expr e |
@@ -967,6 +981,16 @@ private module Cached {
967
981
or
968
982
n .asExpr ( ) = any ( WithExpr we ) .getInitializer ( )
969
983
}
984
+
985
+ cached
986
+ predicate parameterNode ( Node n , DataFlowCallable c , int i ) {
987
+ n .( ParameterNodeImpl ) .isParameterOf ( c , i )
988
+ }
989
+
990
+ cached
991
+ predicate argumentNode ( Node n , DataFlowCall call , int pos ) {
992
+ n .( ArgumentNodeImpl ) .argumentOf ( call , pos )
993
+ }
970
994
}
971
995
972
996
import Cached
@@ -992,8 +1016,6 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
992
1016
}
993
1017
994
1018
abstract class ParameterNodeImpl extends NodeImpl {
995
- abstract DotNet:: Parameter getParameter ( ) ;
996
-
997
1019
abstract predicate isParameterOf ( DataFlowCallable c , int i ) ;
998
1020
}
999
1021
@@ -1010,11 +1032,9 @@ private module ParameterNodes {
1010
1032
/** Gets the SSA definition corresponding to this parameter, if any. */
1011
1033
Ssa:: ExplicitDefinition getSsaDefinition ( ) {
1012
1034
result .getADefinition ( ) .( AssignableDefinitions:: ImplicitParameterDefinition ) .getParameter ( ) =
1013
- this . getParameter ( )
1035
+ parameter
1014
1036
}
1015
1037
1016
- override DotNet:: Parameter getParameter ( ) { result = parameter }
1017
-
1018
1038
override predicate isParameterOf ( DataFlowCallable c , int i ) { c .getParameter ( i ) = parameter }
1019
1039
1020
1040
override DataFlowCallable getEnclosingCallableImpl ( ) { result = parameter .getCallable ( ) }
@@ -1037,8 +1057,6 @@ private module ParameterNodes {
1037
1057
/** Gets the callable containing this implicit instance parameter. */
1038
1058
Callable getCallable ( ) { result = callable }
1039
1059
1040
- override DotNet:: Parameter getParameter ( ) { none ( ) }
1041
-
1042
1060
override predicate isParameterOf ( DataFlowCallable c , int pos ) { callable = c and pos = - 1 }
1043
1061
1044
1062
override DataFlowCallable getEnclosingCallableImpl ( ) { result = callable }
@@ -1113,8 +1131,6 @@ private module ParameterNodes {
1113
1131
/** Gets the captured variable that this implicit parameter models. */
1114
1132
LocalScopeVariable getVariable ( ) { result = def .getVariable ( ) }
1115
1133
1116
- override DotNet:: Parameter getParameter ( ) { none ( ) }
1117
-
1118
1134
override predicate isParameterOf ( DataFlowCallable c , int i ) {
1119
1135
i = getParameterPosition ( def ) and
1120
1136
c = this .getEnclosingCallable ( )
@@ -1125,13 +1141,15 @@ private module ParameterNodes {
1125
1141
import ParameterNodes
1126
1142
1127
1143
/** A data-flow node that represents a call argument. */
1128
- abstract class ArgumentNode extends Node {
1144
+ class ArgumentNode extends Node {
1145
+ ArgumentNode ( ) { argumentNode ( this , _, _) }
1146
+
1129
1147
/** Holds if this argument occurs at the given position in the given call. */
1130
- cached
1131
- abstract predicate argumentOf ( DataFlowCall call , int pos ) ;
1148
+ final predicate argumentOf ( DataFlowCall call , int pos ) { argumentNode ( this , call , pos ) }
1149
+ }
1132
1150
1133
- /** Gets the call in which this node is an argument. */
1134
- final DataFlowCall getCall ( ) { this . argumentOf ( result , _ ) }
1151
+ abstract private class ArgumentNodeImpl extends Node {
1152
+ abstract predicate argumentOf ( DataFlowCall call , int pos ) ;
1135
1153
}
1136
1154
1137
1155
private module ArgumentNodes {
@@ -1149,15 +1167,14 @@ private module ArgumentNodes {
1149
1167
}
1150
1168
1151
1169
/** A data-flow node that represents an explicit call argument. */
1152
- class ExplicitArgumentNode extends ArgumentNode {
1170
+ class ExplicitArgumentNode extends ArgumentNodeImpl {
1153
1171
ExplicitArgumentNode ( ) {
1154
1172
this .asExpr ( ) instanceof Argument
1155
1173
or
1156
1174
this .asExpr ( ) = any ( CIL:: Call call ) .getAnArgument ( )
1157
1175
}
1158
1176
1159
1177
override predicate argumentOf ( DataFlowCall call , int pos ) {
1160
- Stages:: DataFlowStage:: forceCachingInSameStage ( ) and
1161
1178
exists ( ArgumentConfiguration x , Expr c , Argument arg |
1162
1179
arg = this .asExpr ( ) and
1163
1180
c = call .getExpr ( ) and
@@ -1189,7 +1206,8 @@ private module ArgumentNodes {
1189
1206
* } }
1190
1207
* ```
1191
1208
*/
1192
- class ImplicitCapturedArgumentNode extends ArgumentNode , NodeImpl , TImplicitCapturedArgumentNode {
1209
+ class ImplicitCapturedArgumentNode extends ArgumentNodeImpl , NodeImpl ,
1210
+ TImplicitCapturedArgumentNode {
1193
1211
private LocalScopeVariable v ;
1194
1212
private ControlFlow:: Nodes:: ElementNode cfn ;
1195
1213
@@ -1231,7 +1249,7 @@ private module ArgumentNodes {
1231
1249
* A node that corresponds to the value of an object creation (`new C()`) before
1232
1250
* the constructor has run.
1233
1251
*/
1234
- class MallocNode extends ArgumentNode , NodeImpl , TMallocNode {
1252
+ class MallocNode extends ArgumentNodeImpl , NodeImpl , TMallocNode {
1235
1253
private ControlFlow:: Nodes:: ElementNode cfn ;
1236
1254
1237
1255
MallocNode ( ) { this = TMallocNode ( cfn ) }
@@ -1266,7 +1284,7 @@ private module ArgumentNodes {
1266
1284
* and that argument is itself a compatible array, for example
1267
1285
* `Foo(new[] { "a", "b", "c" })`.
1268
1286
*/
1269
- class ParamsArgumentNode extends ArgumentNode , NodeImpl , TParamsArgumentNode {
1287
+ class ParamsArgumentNode extends ArgumentNodeImpl , NodeImpl , TParamsArgumentNode {
1270
1288
private ControlFlow:: Node callCfn ;
1271
1289
1272
1290
ParamsArgumentNode ( ) { this = TParamsArgumentNode ( callCfn ) }
@@ -1291,7 +1309,7 @@ private module ArgumentNodes {
1291
1309
override string toStringImpl ( ) { result = "[implicit array creation] " + callCfn }
1292
1310
}
1293
1311
1294
- private class SummaryArgumentNode extends SummaryNode , ArgumentNode {
1312
+ private class SummaryArgumentNode extends SummaryNode , ArgumentNodeImpl {
1295
1313
private DataFlowCall c ;
1296
1314
private int i ;
1297
1315
@@ -1324,10 +1342,7 @@ private module ReturnNodes {
1324
1342
)
1325
1343
}
1326
1344
1327
- override NormalReturnKind getKind ( ) {
1328
- any ( DotNet:: Callable c ) .canReturn ( this .getExpr ( ) ) and
1329
- exists ( result )
1330
- }
1345
+ override NormalReturnKind getKind ( ) { exists ( result ) }
1331
1346
}
1332
1347
1333
1348
/**
@@ -1744,7 +1759,10 @@ class DataFlowType extends Gvn::GvnType {
1744
1759
}
1745
1760
1746
1761
/** Gets the type of `n` used for type pruning. */
1747
- DataFlowType getNodeType ( NodeImpl n ) { result = n .getDataFlowType ( ) }
1762
+ pragma [ inline]
1763
+ Gvn:: GvnType getNodeType ( NodeImpl n ) {
1764
+ pragma [ only_bind_into ] ( result ) = pragma [ only_bind_out ] ( n ) .getDataFlowType ( )
1765
+ }
1748
1766
1749
1767
/** Gets a string representation of a `DataFlowType`. */
1750
1768
string ppReprType ( DataFlowType t ) { result = t .toString ( ) }
@@ -1819,7 +1837,8 @@ private module PostUpdateNodes {
1819
1837
* Such a node acts as both a post-update node for the `MallocNode`, as well as
1820
1838
* a pre-update node for the `ObjectCreationNode`.
1821
1839
*/
1822
- class ObjectInitializerNode extends PostUpdateNode , NodeImpl , ArgumentNode , TObjectInitializerNode {
1840
+ class ObjectInitializerNode extends PostUpdateNode , NodeImpl , ArgumentNodeImpl ,
1841
+ TObjectInitializerNode {
1823
1842
private ObjectCreation oc ;
1824
1843
private ControlFlow:: Nodes:: ElementNode cfn ;
1825
1844
0 commit comments