Skip to content

Commit 58a1353

Browse files
committed
C#: Clean up implementation and remove CIL dataflow implementation.
1 parent 1638183 commit 58a1353

File tree

20 files changed

+68
-380
lines changed

20 files changed

+68
-380
lines changed

csharp/ql/lib/semmle/code/cil/Declaration.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration {
4242
}
4343
}
4444

45-
private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) }
45+
private CS::Declaration toCSharpNonTypeParameter(Declaration d) {
46+
result.(DotNet::Declaration).matchesHandle(d)
47+
}
4648

4749
private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
4850
toCSharpTypeParameterJoin(tp, result.getIndex(), result.getGeneric())

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
private import semmle.code.csharp.commons.QualifiedName
44
import Element
55
import Type
6-
private import dotnet
76

87
/**
98
* A type container. Either a namespace (`Namespace`) or a type (`Type`).

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import Member
66
import Stmt
77
import Type
8-
private import cil
9-
private import dotnet
108
private import semmle.code.csharp.ExprOrStmtParent
119
private import TypeRef
1210

@@ -558,8 +556,6 @@ class TrivialProperty extends Property {
558556
this.isAutoImplemented()
559557
or
560558
this.getGetter().trivialGetterField() = this.getSetter().trivialSetterField()
561-
or
562-
exists(CIL::TrivialProperty prop | this.matchesHandle(prop))
563559
}
564560
}
565561

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import Assignable
77
import Callable
88
import Element
99
import Type
10-
private import dotnet
1110
private import semmle.code.csharp.ExprOrStmtParent
1211
private import TypeRef
1312

csharp/ql/lib/semmle/code/csharp/commons/Disposal.qll

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,13 @@
33
*/
44

55
import csharp
6-
private import cil
7-
private import dotnet
86

9-
private predicate isDisposeMethod(DotNet::Callable method) {
7+
private predicate isDisposeMethod(Callable method) {
108
method.getName() = "Dispose" and
119
method.getNumberOfParameters() = 0
1210
}
1311

14-
private predicate cilVariableReadFlowsToNode(CIL::Variable variable, DataFlow::Node n) {
15-
n.asExpr() = variable.getARead()
16-
or
17-
exists(DataFlow::Node mid |
18-
cilVariableReadFlowsToNode(variable, mid) and
19-
DataFlow::localFlowStep(mid, n)
20-
)
21-
}
22-
23-
private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) {
24-
cilVariableReadFlowsToNode(variable, DataFlow::exprNode(n))
25-
}
26-
27-
private predicate disposedCilVariable(CIL::Variable variable) {
28-
// `variable` is the `this` parameter on a dispose method.
29-
isDisposeMethod(variable.(CIL::ThisParameter).getMethod())
30-
or
31-
// `variable` is passed to a method that disposes it.
32-
exists(CIL::Call call, CIL::Parameter param |
33-
cilVariableReadFlowsTo(variable, call.getArgumentForParameter(param)) and
34-
disposedCilVariable(param)
35-
)
36-
or
37-
// A parameter is disposed if its source declaration is disposed
38-
disposedCilVariable(variable.(CIL::Parameter).getUnboundDeclaration())
39-
or
40-
// A variable is disposed if it's assigned to another variable
41-
// that may be disposed.
42-
exists(CIL::WriteAccess write |
43-
cilVariableReadFlowsTo(variable, write.getExpr()) and
44-
disposedCilVariable(write.getTarget())
45-
)
46-
}
47-
4812
private predicate disposedCSharpVariable(Variable variable) {
49-
// A C# parameter is disposed if its corresponding CIL parameter is disposed
50-
exists(CIL::Method m, CIL::Parameter p, int i |
51-
disposedCilVariable(p) and p = m.getRawParameter(i)
52-
|
53-
variable = any(Callable c2 | c2.matchesHandle(m)).getRawParameter(i)
54-
)
55-
or
5613
// Call to a method that disposes it
5714
exists(Call call, int arg, VariableRead read |
5815
read.getTarget() = variable and
@@ -83,7 +40,4 @@ private predicate disposedCSharpVariable(Variable variable) {
8340
* Hold if `variable` might be disposed.
8441
* This is a conservative overestimate.
8542
*/
86-
predicate mayBeDisposed(DotNet::Variable variable) {
87-
disposedCSharpVariable(variable) or
88-
disposedCilVariable(variable)
89-
}
43+
predicate mayBeDisposed(Variable variable) { disposedCSharpVariable(variable) }

csharp/ql/lib/semmle/code/csharp/commons/QualifiedName.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
/** Provides predicates for working with fully qualified names. */
22

33
private import csharp
4-
private import dotnet
54

65
/**
76
* Holds if namespace `n` has the qualified name `qualifier`.`name`.
87
*
98
* For example if the qualified name is `System.Collections.Generic`, then
109
* `qualifier`=`System.Collections` and `name`=`Generic`.
1110
*/
12-
predicate namespaceHasQualifiedName(DotNet::Namespace n, string qualifier, string name) {
13-
if n instanceof DotNet::GlobalNamespace
11+
predicate namespaceHasQualifiedName(Namespace n, string qualifier, string name) {
12+
if n instanceof GlobalNamespace
1413
then qualifier = "" and name = ""
1514
else (
1615
exists(string pqualifier, string pname |

csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import csharp
66
private import cil
7-
private import dotnet
87
private import ControlFlow::SuccessorTypes
98
private import semmle.code.csharp.commons.Assertions
109
private import semmle.code.csharp.commons.ComparisonTest
@@ -844,8 +843,6 @@ class NullGuardedDataFlowNode extends GuardedDataFlowNode {
844843

845844
/** INTERNAL: Do not use. */
846845
module Internal {
847-
private import semmle.code.cil.CallableReturns
848-
849846
newtype TAbstractValue =
850847
TBooleanValue(boolean b) { b = true or b = false } or
851848
TIntegerValue(int i) { i = any(Expr e).getValue().toInt() } or
@@ -856,20 +853,11 @@ module Internal {
856853
} or
857854
TEmptyCollectionValue(boolean b) { b = true or b = false }
858855

859-
/** A callable that always returns a `null` value. */
860-
private class NullCallable extends Callable {
861-
NullCallable() {
862-
exists(CIL::Method m | m.matchesHandle(this) | alwaysNullMethod(m) and not m.isVirtual())
863-
}
864-
}
865-
866856
/** Holds if expression `e` is a `null` value. */
867857
predicate nullValue(Expr e) {
868858
e instanceof NullLiteral
869859
or
870860
e instanceof DefaultValueExpr and e.getType().isRefType()
871-
or
872-
e.(Call).getTarget().getUnboundDeclaration() instanceof NullCallable
873861
}
874862

875863
/** Holds if expression `e2` is a `null` value whenever `e1` is. */
@@ -890,11 +878,7 @@ module Internal {
890878

891879
/** A callable that always returns a non-`null` value. */
892880
private class NonNullCallable extends Callable {
893-
NonNullCallable() {
894-
exists(CIL::Method m | m.matchesHandle(this) | alwaysNotNullMethod(m) and not m.isVirtual())
895-
or
896-
this = any(SystemObjectClass c).getGetTypeMethod()
897-
}
881+
NonNullCallable() { this = any(SystemObjectClass c).getGetTypeMethod() }
898882
}
899883

900884
/** Holds if expression `e` is a non-`null` value. */

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
*/
77

88
import csharp
9-
private import cil
10-
private import semmle.code.cil.CallableReturns
119
private import semmle.code.csharp.ExprOrStmtParent
1210
private import semmle.code.csharp.commons.Assertions
1311
private import semmle.code.csharp.frameworks.System
@@ -39,15 +37,6 @@ private class ThrowingCall extends NonReturningCall {
3937
or
4038
this.(FailingAssertion).getAssertionFailure().isException(c.getExceptionClass())
4139
or
42-
exists(Callable target, CIL::Method m, CIL::Type ex |
43-
target = this.getTarget() and
44-
not target.hasBody() and
45-
target.matchesHandle(m) and
46-
alwaysThrowsException(m, ex) and
47-
c.getExceptionClass().matchesHandle(ex) and
48-
not m.isVirtual()
49-
)
50-
or
5140
this =
5241
any(MethodCall mc |
5342
mc.getTarget()

csharp/ql/lib/semmle/code/csharp/dataflow/internal/CallableReturns.qll

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
*/
44

55
import csharp
6-
private import cil
76
private import semmle.code.csharp.dataflow.Nullness
8-
private import semmle.code.cil.CallableReturns as CR
97

108
private predicate finalCallable(Callable c) {
119
not c.(Virtualizable).isVirtual() and
@@ -15,19 +13,11 @@ private predicate finalCallable(Callable c) {
1513
/** Holds if callable `c` always returns null. */
1614
predicate alwaysNullCallable(Callable c) {
1715
finalCallable(c) and
18-
(
19-
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNullMethod(m))
20-
or
21-
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
22-
)
16+
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
2317
}
2418

2519
/** Holds if callable `c` always returns a non-null value. */
2620
predicate alwaysNotNullCallable(Callable c) {
2721
finalCallable(c) and
28-
(
29-
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNotNullMethod(m))
30-
or
31-
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
32-
)
22+
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
3323
}

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
private import csharp
2-
private import cil
3-
private import dotnet
42
private import DataFlowImplCommon as DataFlowImplCommon
53
private import DataFlowPublic
64
private import DataFlowPrivate
@@ -14,29 +12,12 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
1412
/**
1513
* Gets a source declaration of callable `c` that has a body or has
1614
* a flow summary.
17-
*
18-
* If the callable has both CIL and source code, return only the source
19-
* code version.
2015
*/
21-
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
22-
exists(DotNet::Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() |
23-
result.hasBody() and
24-
if unboundDecl.getFile().fromSource()
25-
then
26-
// C# callable with C# implementation in the database
27-
result = unboundDecl
28-
else
29-
if unboundDecl instanceof CIL::Callable
30-
then
31-
// CIL callable with C# implementation in the database
32-
unboundDecl.matchesHandle(result.(Callable))
33-
or
34-
// CIL callable without C# implementation in the database
35-
not unboundDecl.matchesHandle(any(Callable k | k.hasBody())) and
36-
result = unboundDecl
37-
else
38-
// C# callable without C# implementation in the database
39-
unboundDecl.matchesHandle(result.(CIL::Callable))
16+
Callable getCallableForDataFlow(Callable c) {
17+
exists(Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() |
18+
unboundDecl.hasBody() and
19+
unboundDecl.getFile().fromSource() and
20+
result = unboundDecl
4021
)
4122
}
4223

@@ -67,7 +48,7 @@ private module Cached {
6748
*/
6849
cached
6950
newtype TDataFlowCallable =
70-
TDotNetCallable(DotNet::Callable c) { c.isUnboundDeclaration() } or
51+
TCallable(Callable c) { c.isUnboundDeclaration() } or
7152
TSummarizedCallable(DataFlowSummarizedCallable sc) or
7253
TFieldOrPropertyCallable(FieldOrProperty f) or
7354
TCapturedVariableCallable(LocalScopeVariable v) { v.isCaptured() }
@@ -81,10 +62,6 @@ private module Cached {
8162
TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) {
8263
cfn.getAstNode() = dc
8364
} or
84-
TCilCall(CIL::Call call) {
85-
// No need to include calls that are compiled from source
86-
not call.getImplementation().getMethod().compiledFromSource()
87-
} or
8865
TSummaryCall(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) {
8966
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
9067
}
@@ -197,7 +174,7 @@ class RefReturnKind extends OutRefReturnKind, TRefReturnKind {
197174
/** A callable used for data flow. */
198175
class DataFlowCallable extends TDataFlowCallable {
199176
/** Gets the underlying source code callable, if any. */
200-
DotNet::Callable asCallable() { this = TDotNetCallable(result) }
177+
Callable asCallable() { this = TCallable(result) }
201178

202179
/** Gets the underlying summarized callable, if any. */
203180
FlowSummary::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
@@ -208,7 +185,7 @@ class DataFlowCallable extends TDataFlowCallable {
208185
LocalScopeVariable asCapturedVariable() { this = TCapturedVariableCallable(result) }
209186

210187
/** Gets the underlying callable. */
211-
DotNet::Callable getUnderlyingCallable() {
188+
Callable getUnderlyingCallable() {
212189
result = this.asCallable() or result = this.asSummarizedCallable()
213190
}
214191

@@ -235,8 +212,7 @@ class DataFlowCallable extends TDataFlowCallable {
235212
abstract class DataFlowCall extends TDataFlowCall {
236213
/**
237214
* Gets a run-time target of this call. A target is always a source
238-
* declaration, and if the callable has both CIL and source code, only
239-
* the source code version is returned.
215+
* declaration.
240216
*/
241217
abstract DataFlowCallable getARuntimeTarget();
242218

@@ -250,7 +226,7 @@ abstract class DataFlowCall extends TDataFlowCall {
250226
abstract DataFlowCallable getEnclosingCallable();
251227

252228
/** Gets the underlying expression, if any. */
253-
final DotNet::Expr getExpr() { result = this.getNode().asExpr() }
229+
final Expr getExpr() { result = this.getNode().asExpr() }
254230

255231
/** Gets the argument at position `pos` of this call. */
256232
final ArgumentNode getArgument(ArgumentPosition pos) { result.argumentOf(this, pos) }
@@ -348,33 +324,6 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
348324
override Location getLocation() { result = cfn.getLocation() }
349325
}
350326

351-
/** A CIL call relevant for data flow. */
352-
class CilDataFlowCall extends DataFlowCall, TCilCall {
353-
private CIL::Call call;
354-
355-
CilDataFlowCall() { this = TCilCall(call) }
356-
357-
/** Gets the underlying CIL call. */
358-
CIL::Call getCilCall() { result = call }
359-
360-
override DataFlowCallable getARuntimeTarget() {
361-
// There is no dispatch library for CIL, so do not consider overrides for now
362-
result.getUnderlyingCallable() = getCallableForDataFlow(call.getTarget())
363-
}
364-
365-
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
366-
367-
override DataFlow::ExprNode getNode() { result.getExpr() = call }
368-
369-
override DataFlowCallable getEnclosingCallable() {
370-
result.asCallable() = call.getEnclosingCallable()
371-
}
372-
373-
override string toString() { result = call.toString() }
374-
375-
override Location getLocation() { result = call.getLocation() }
376-
}
377-
378327
/**
379328
* A synthesized call inside a callable with a flow summary.
380329
*

0 commit comments

Comments
 (0)