Skip to content

Commit 8006866

Browse files
committed
C#: Refactor data-flow predicates defined by dispatch
1 parent d4e1ee8 commit 8006866

File tree

3 files changed

+127
-83
lines changed

3 files changed

+127
-83
lines changed

csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 106 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,42 @@ private import semmle.code.csharp.dispatch.Dispatch
1616
private import semmle.code.csharp.frameworks.EntityFramework
1717
private import semmle.code.csharp.frameworks.NHibernate
1818

19+
abstract class NodeImpl extends Node {
20+
/** Do not call: use `getEnclosingCallable()` instead. */
21+
abstract DataFlowCallable getEnclosingCallableImpl();
22+
23+
/** Do not call: use `getType()` instead. */
24+
abstract DotNet::Type getTypeImpl();
25+
26+
/** Do not call: use `getControlFlowNode()` instead. */
27+
abstract ControlFlow::Node getControlFlowNodeImpl();
28+
29+
/** Do not call: use `getLocation()` instead. */
30+
abstract Location getLocationImpl();
31+
32+
/** Do not call: use `toString()` instead. */
33+
abstract string toStringImpl();
34+
}
35+
36+
private class ExprNodeImpl extends ExprNode, NodeImpl {
37+
override DataFlowCallable getEnclosingCallableImpl() {
38+
result = this.getExpr().getEnclosingCallable()
39+
}
40+
41+
override DotNet::Type getTypeImpl() { result = this.getExpr().getType() }
42+
43+
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { this = TExprNode(result) }
44+
45+
override Location getLocationImpl() { result = this.getExpr().getLocation() }
46+
47+
override string toStringImpl() {
48+
result = this.getControlFlowNode().toString()
49+
or
50+
this = TCilExprNode(_) and
51+
result = "CIL expression"
52+
}
53+
}
54+
1955
/** Calculation of the relative order in which `this` references are read. */
2056
private module ThisFlow {
2157
private class BasicBlock = ControlFlow::BasicBlock;
@@ -553,27 +589,31 @@ private module Cached {
553589
import Cached
554590

555591
/** An SSA definition, viewed as a node in a data flow graph. */
556-
class SsaDefinitionNode extends Node, TSsaDefinitionNode {
592+
class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
557593
Ssa::Definition def;
558594

559595
SsaDefinitionNode() { this = TSsaDefinitionNode(def) }
560596

561597
/** Gets the underlying SSA definition. */
562598
Ssa::Definition getDefinition() { result = def }
563599

564-
override Callable getEnclosingCallable() { result = def.getEnclosingCallable() }
600+
override Callable getEnclosingCallableImpl() { result = def.getEnclosingCallable() }
565601

566-
override Type getType() { result = def.getSourceVariable().getType() }
602+
override Type getTypeImpl() { result = def.getSourceVariable().getType() }
567603

568-
override Location getLocation() { result = def.getLocation() }
604+
override ControlFlow::Node getControlFlowNodeImpl() { result = def.getControlFlowNode() }
569605

570-
override string toString() {
606+
override Location getLocationImpl() { result = def.getLocation() }
607+
608+
override string toStringImpl() {
571609
not explicitParameterNode(this, _) and
572610
result = def.toString()
573611
}
574612
}
575613

576614
private module ParameterNodes {
615+
abstract private class ParameterNodeImpl extends ParameterNode, NodeImpl { }
616+
577617
/**
578618
* Holds if definition node `node` is an entry definition for parameter `p`.
579619
*/
@@ -585,7 +625,7 @@ private module ParameterNodes {
585625
* The value of an explicit parameter at function entry, viewed as a node in a data
586626
* flow graph.
587627
*/
588-
class ExplicitParameterNode extends ParameterNode {
628+
class ExplicitParameterNode extends ParameterNodeImpl {
589629
private DotNet::Parameter parameter;
590630

591631
ExplicitParameterNode() {
@@ -597,17 +637,19 @@ private module ParameterNodes {
597637

598638
override predicate isParameterOf(DataFlowCallable c, int i) { c.getParameter(i) = parameter }
599639

600-
override DotNet::Callable getEnclosingCallable() { result = parameter.getCallable() }
640+
override DotNet::Callable getEnclosingCallableImpl() { result = parameter.getCallable() }
641+
642+
override DotNet::Type getTypeImpl() { result = parameter.getType() }
601643

602-
override DotNet::Type getType() { result = parameter.getType() }
644+
override ControlFlow::Node getControlFlowNodeImpl() { none() }
603645

604-
override Location getLocation() { result = parameter.getLocation() }
646+
override Location getLocationImpl() { result = parameter.getLocation() }
605647

606-
override string toString() { result = parameter.toString() }
648+
override string toStringImpl() { result = parameter.toString() }
607649
}
608650

609651
/** An implicit instance (`this`) parameter. */
610-
class InstanceParameterNode extends ParameterNode, TInstanceParameterNode {
652+
class InstanceParameterNode extends ParameterNodeImpl, TInstanceParameterNode {
611653
private Callable callable;
612654

613655
InstanceParameterNode() { this = TInstanceParameterNode(callable) }
@@ -617,13 +659,15 @@ private module ParameterNodes {
617659

618660
override predicate isParameterOf(DataFlowCallable c, int pos) { callable = c and pos = -1 }
619661

620-
override Callable getEnclosingCallable() { result = callable }
662+
override Callable getEnclosingCallableImpl() { result = callable }
621663

622-
override Type getType() { result = callable.getDeclaringType() }
664+
override Type getTypeImpl() { result = callable.getDeclaringType() }
623665

624-
override Location getLocation() { result = callable.getLocation() }
666+
override ControlFlow::Node getControlFlowNodeImpl() { none() }
625667

626-
override string toString() { result = "this" }
668+
override Location getLocationImpl() { result = callable.getLocation() }
669+
670+
override string toStringImpl() { result = "this" }
627671
}
628672

629673
module ImplicitCapturedParameterNodeImpl {
@@ -776,7 +820,7 @@ private module ArgumentNodes {
776820
* } }
777821
* ```
778822
*/
779-
class ImplicitCapturedArgumentNode extends ArgumentNode, TImplicitCapturedArgumentNode {
823+
class ImplicitCapturedArgumentNode extends ArgumentNode, NodeImpl, TImplicitCapturedArgumentNode {
780824
private LocalScopeVariable v;
781825
private ControlFlow::Nodes::ElementNode cfn;
782826

@@ -814,20 +858,22 @@ private module ArgumentNodes {
814858
)
815859
}
816860

817-
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
861+
override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
862+
863+
override Type getTypeImpl() { result = v.getType() }
818864

819-
override Type getType() { result = v.getType() }
865+
override ControlFlow::Node getControlFlowNodeImpl() { none() }
820866

821-
override Location getLocation() { result = cfn.getLocation() }
867+
override Location getLocationImpl() { result = cfn.getLocation() }
822868

823-
override string toString() { result = "[implicit argument] " + v }
869+
override string toStringImpl() { result = "[implicit argument] " + v }
824870
}
825871

826872
/**
827873
* A node that corresponds to the value of an object creation (`new C()`) before
828874
* the constructor has run.
829875
*/
830-
class MallocNode extends ArgumentNode, TMallocNode {
876+
class MallocNode extends ArgumentNode, NodeImpl, TMallocNode {
831877
private ControlFlow::Nodes::ElementNode cfn;
832878

833879
MallocNode() { this = TMallocNode(cfn) }
@@ -837,15 +883,15 @@ private module ArgumentNodes {
837883
pos = -1
838884
}
839885

840-
override ControlFlow::Node getControlFlowNode() { result = cfn }
886+
override ControlFlow::Node getControlFlowNodeImpl() { result = cfn }
841887

842-
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
888+
override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
843889

844-
override Type getType() { result = cfn.getElement().(Expr).getType() }
890+
override Type getTypeImpl() { result = cfn.getElement().(Expr).getType() }
845891

846-
override Location getLocation() { result = cfn.getLocation() }
892+
override Location getLocationImpl() { result = cfn.getLocation() }
847893

848-
override string toString() { result = "malloc" }
894+
override string toStringImpl() { result = "malloc" }
849895
}
850896

851897
/**
@@ -858,7 +904,7 @@ private module ArgumentNodes {
858904
*
859905
* `x` is an implicit argument of the implicit call to `Foo`.
860906
*/
861-
class ImplicitDelegateArgumentNode extends ArgumentNode, TImplicitDelegateArgumentNode {
907+
class ImplicitDelegateArgumentNode extends ArgumentNode, NodeImpl, TImplicitDelegateArgumentNode {
862908
private ControlFlow::Node cfn;
863909
private int delegateIndex;
864910
private int parameterIndex;
@@ -874,15 +920,17 @@ private module ArgumentNodes {
874920
pos = parameterIndex
875921
}
876922

877-
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
923+
override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
878924

879-
override Type getType() {
925+
override Type getTypeImpl() {
880926
result = this.getDelegateCall().getDelegateParameterType(parameterIndex)
881927
}
882928

883-
override Location getLocation() { result = cfn.getLocation() }
929+
override ControlFlow::Node getControlFlowNodeImpl() { none() }
930+
931+
override Location getLocationImpl() { result = cfn.getLocation() }
884932

885-
override string toString() { result = "[implicit argument " + parameterIndex + "] " + cfn }
933+
override string toStringImpl() { result = "[implicit argument " + parameterIndex + "] " + cfn }
886934
}
887935
}
888936

@@ -939,7 +987,7 @@ private module ReturnNodes {
939987
* `yield return`s as stores into collections, i.e., there is flow from `e`
940988
* to `yield return e [e]`.
941989
*/
942-
class YieldReturnNode extends ReturnNode, PostUpdateNode, TYieldReturnNode {
990+
class YieldReturnNode extends ReturnNode, NodeImpl, TYieldReturnNode {
943991
private ControlFlow::Nodes::ElementNode cfn;
944992
private YieldReturnStmt yrs;
945993

@@ -949,15 +997,15 @@ private module ReturnNodes {
949997

950998
override YieldReturnKind getKind() { any() }
951999

952-
override ExprNode getPreUpdateNode() { result.getControlFlowNode() = cfn }
1000+
override Callable getEnclosingCallableImpl() { result = yrs.getEnclosingCallable() }
9531001

954-
override Callable getEnclosingCallable() { result = yrs.getEnclosingCallable() }
1002+
override Type getTypeImpl() { result = yrs.getEnclosingCallable().getReturnType() }
9551003

956-
override Type getType() { result = yrs.getEnclosingCallable().getReturnType() }
1004+
override ControlFlow::Node getControlFlowNodeImpl() { result = cfn }
9571005

958-
override Location getLocation() { result = yrs.getLocation() }
1006+
override Location getLocationImpl() { result = yrs.getLocation() }
9591007

960-
override string toString() { result = yrs.toString() }
1008+
override string toStringImpl() { result = yrs.toString() }
9611009
}
9621010

9631011
/**
@@ -1112,7 +1160,7 @@ private module OutNodes {
11121160
* in a call to a library method. For example, the output from the implicit
11131161
* call to `M` in `new Lazy<int>(M)`.
11141162
*/
1115-
class ImplicitDelegateOutNode extends OutNode, TImplicitDelegateOutNode {
1163+
class ImplicitDelegateOutNode extends OutNode, NodeImpl, TImplicitDelegateOutNode {
11161164
private ControlFlow::Nodes::ElementNode cfn;
11171165
private ControlFlow::Nodes::ElementNode call;
11181166

@@ -1128,7 +1176,7 @@ private module OutNodes {
11281176
call.getElement().(Call).getArgument(i) = cfn.getElement()
11291177
}
11301178

1131-
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
1179+
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { result = cfn }
11321180

11331181
override ImplicitDelegateDataFlowCall getCall(ReturnKind kind) {
11341182
result.getNode() = this and
@@ -1141,17 +1189,17 @@ private module OutNodes {
11411189
)
11421190
}
11431191

1144-
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
1192+
override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
11451193

1146-
override Type getType() {
1194+
override Type getTypeImpl() {
11471195
exists(ImplicitDelegateDataFlowCall c | c.getNode() = this |
11481196
result = c.getDelegateReturnType()
11491197
)
11501198
}
11511199

1152-
override Location getLocation() { result = cfn.getLocation() }
1200+
override Location getLocationImpl() { result = cfn.getLocation() }
11531201

1154-
override string toString() { result = "[output] " + cfn }
1202+
override string toStringImpl() { result = "[output] " + cfn }
11551203
}
11561204
}
11571205

@@ -1320,7 +1368,7 @@ module LibraryFlow {
13201368
}
13211369

13221370
/** A data-flow node used to model flow through library code. */
1323-
class LibraryCodeNode extends Node, TLibraryCodeNode {
1371+
class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
13241372
private ControlFlow::Node callCfn;
13251373
private CallableFlowSource source;
13261374
private AccessPath sourceAp;
@@ -1413,7 +1461,7 @@ class LibraryCodeNode extends Node, TLibraryCodeNode {
14131461
)
14141462
}
14151463

1416-
override Callable getEnclosingCallable() { result = callCfn.getEnclosingCallable() }
1464+
override Callable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() }
14171465

14181466
override DataFlowType getTypeBound() {
14191467
preservesValue = true and
@@ -1426,9 +1474,13 @@ class LibraryCodeNode extends Node, TLibraryCodeNode {
14261474
result = this.getSuccessor(_).getTypeBound()
14271475
}
14281476

1429-
override Location getLocation() { result = callCfn.getLocation() }
1477+
override DotNet::Type getTypeImpl() { none() }
14301478

1431-
override string toString() { result = "[library code] " + callCfn }
1479+
override ControlFlow::Node getControlFlowNodeImpl() { result = callCfn }
1480+
1481+
override Location getLocationImpl() { result = callCfn.getLocation() }
1482+
1483+
override string toStringImpl() { result = "[library code] " + callCfn }
14321484
}
14331485

14341486
/** A field or a property. */
@@ -1600,20 +1652,22 @@ private module PostUpdateNodes {
16001652
override MallocNode getPreUpdateNode() { this = TExprNode(result.getControlFlowNode()) }
16011653
}
16021654

1603-
class ExprPostUpdateNode extends PostUpdateNode, TExprPostUpdateNode {
1655+
class ExprPostUpdateNode extends PostUpdateNode, NodeImpl, TExprPostUpdateNode {
16041656
private ControlFlow::Nodes::ElementNode cfn;
16051657

16061658
ExprPostUpdateNode() { this = TExprPostUpdateNode(cfn) }
16071659

16081660
override ExprNode getPreUpdateNode() { cfn = result.getControlFlowNode() }
16091661

1610-
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
1662+
override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
1663+
1664+
override Type getTypeImpl() { result = cfn.getElement().(Expr).getType() }
16111665

1612-
override Type getType() { result = cfn.getElement().(Expr).getType() }
1666+
override ControlFlow::Node getControlFlowNodeImpl() { none() }
16131667

1614-
override Location getLocation() { result = cfn.getLocation() }
1668+
override Location getLocationImpl() { result = cfn.getLocation() }
16151669

1616-
override string toString() { result = "[post] " + cfn.toString() }
1670+
override string toStringImpl() { result = "[post] " + cfn.toString() }
16171671
}
16181672
}
16191673

0 commit comments

Comments
 (0)