@@ -24,10 +24,8 @@ private class ReturnNode extends DataFlow::ExprNode {
24
24
}
25
25
}
26
26
27
- private class Conf extends DataFlow:: Configuration {
28
- Conf ( ) { this = "NoDisposeCallOnLocalIDisposable" }
29
-
30
- override predicate isSource ( DataFlow:: Node node ) {
27
+ module DisposeCallOnLocalIDisposableConfig implements DataFlow:: ConfigSig {
28
+ predicate isSource ( DataFlow:: Node node ) {
31
29
node .asExpr ( ) =
32
30
any ( LocalScopeDisposableCreation disposable |
33
31
// Only care about library types - user types often have spurious IDisposable declarations
@@ -37,7 +35,7 @@ private class Conf extends DataFlow::Configuration {
37
35
)
38
36
}
39
37
40
- override predicate isSink ( DataFlow:: Node node ) {
38
+ predicate isSink ( DataFlow:: Node node ) {
41
39
// Things that return may be disposed elsewhere
42
40
node instanceof ReturnNode
43
41
or
@@ -80,23 +78,27 @@ private class Conf extends DataFlow::Configuration {
80
78
)
81
79
}
82
80
83
- override predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
81
+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
84
82
node2 .asExpr ( ) =
85
83
any ( LocalScopeDisposableCreation other | other .getAnArgument ( ) = node1 .asExpr ( ) )
86
84
}
87
85
88
- override predicate isBarrierOut ( DataFlow:: Node node ) {
89
- this . isSink ( node ) and
86
+ predicate isBarrierOut ( DataFlow:: Node node ) {
87
+ isSink ( node ) and
90
88
not node instanceof ReturnNode
91
89
}
92
90
}
93
91
92
+ module DisposeCallOnLocalIDisposable = DataFlow:: Global< DisposeCallOnLocalIDisposableConfig > ;
93
+
94
94
/** Holds if `disposable` may not be disposed. */
95
95
predicate mayNotBeDisposed ( LocalScopeDisposableCreation disposable ) {
96
- exists ( Conf conf , DataFlow:: ExprNode e |
96
+ exists ( DataFlow:: ExprNode e |
97
97
e .getExpr ( ) = disposable and
98
- conf .isSource ( e ) and
99
- not exists ( DataFlow:: Node sink | conf .hasFlow ( DataFlow:: exprNode ( disposable ) , sink ) |
98
+ DisposeCallOnLocalIDisposableConfig:: isSource ( e ) and
99
+ not exists ( DataFlow:: Node sink |
100
+ DisposeCallOnLocalIDisposable:: flow ( DataFlow:: exprNode ( disposable ) , sink )
101
+ |
100
102
sink instanceof ReturnNode
101
103
implies
102
104
sink .getEnclosingCallable ( ) = disposable .getEnclosingCallable ( )
0 commit comments