Skip to content

Commit 6bcb8a3

Browse files
committed
C#: Replace getErasedRepr() and getTypeBound() with getNodeType()
1 parent 8ff8b3e commit 6bcb8a3

File tree

6 files changed

+55
-69
lines changed

6 files changed

+55
-69
lines changed

csharp/ql/src/semmle/code/csharp/Caching.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ module Stages {
6868
or
6969
exists(any(DataFlow::Node n).getType())
7070
or
71-
exists(any(DataFlow::Node n).getTypeBound())
71+
exists(any(NodeImpl n).getDataFlowType())
7272
or
7373
exists(any(DataFlow::Node n).getLocation())
7474
or

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,11 +1124,11 @@ private module LocalFlowBigStep {
11241124
(
11251125
localFlowStepNodeCand1(node1, node2, config) and
11261126
preservesValue = true and
1127-
t = getErasedNodeTypeBound(node1)
1127+
t = getNodeType(node1)
11281128
or
11291129
additionalLocalFlowStepNodeCand2(node1, node2, config) and
11301130
preservesValue = false and
1131-
t = getErasedNodeTypeBound(node2)
1131+
t = getNodeType(node2)
11321132
) and
11331133
node1 != node2 and
11341134
cc.relevantFor(node1.getEnclosingCallable()) and
@@ -1147,7 +1147,7 @@ private module LocalFlowBigStep {
11471147
additionalLocalFlowStepNodeCand2(mid, node2, config) and
11481148
not mid instanceof FlowCheckNode and
11491149
preservesValue = false and
1150-
t = getErasedNodeTypeBound(node2) and
1150+
t = getNodeType(node2) and
11511151
nodeCand2(node2, unbind(config))
11521152
)
11531153
)
@@ -1202,9 +1202,7 @@ private predicate flowCandFwd(
12021202
) {
12031203
flowCandFwd0(node, fromArg, argApf, apf, config) and
12041204
not apf.isClearedAt(node) and
1205-
if node instanceof CastingNode
1206-
then compatibleTypes(getErasedNodeTypeBound(node), apf.getType())
1207-
else any()
1205+
if node instanceof CastingNode then compatibleTypes(getNodeType(node), apf.getType()) else any()
12081206
}
12091207

12101208
pragma[nomagic]
@@ -1216,7 +1214,7 @@ private predicate flowCandFwd0(
12161214
config.isSource(node) and
12171215
fromArg = false and
12181216
argApf = TAccessPathFrontNone() and
1219-
apf = TFrontNil(getErasedNodeTypeBound(node))
1217+
apf = TFrontNil(getNodeType(node))
12201218
or
12211219
exists(Node mid |
12221220
flowCandFwd(mid, fromArg, argApf, apf, config) and
@@ -1242,7 +1240,7 @@ private predicate flowCandFwd0(
12421240
additionalJumpStep(mid, node, config) and
12431241
fromArg = false and
12441242
argApf = TAccessPathFrontNone() and
1245-
apf = TFrontNil(getErasedNodeTypeBound(node))
1243+
apf = TFrontNil(getNodeType(node))
12461244
)
12471245
or
12481246
// store
@@ -1672,7 +1670,7 @@ private predicate flowFwd0(
16721670
config.isSource(node) and
16731671
fromArg = false and
16741672
argAp = TAccessPathNone() and
1675-
ap = TNil(getErasedNodeTypeBound(node)) and
1673+
ap = TNil(getNodeType(node)) and
16761674
apf = ap.(AccessPathNil).getFront()
16771675
or
16781676
flowCand(node, _, _, _, unbind(config)) and
@@ -1700,7 +1698,7 @@ private predicate flowFwd0(
17001698
additionalJumpStep(mid, node, config) and
17011699
fromArg = false and
17021700
argAp = TAccessPathNone() and
1703-
ap = TNil(getErasedNodeTypeBound(node)) and
1701+
ap = TNil(getNodeType(node)) and
17041702
apf = ap.(AccessPathNil).getFront()
17051703
)
17061704
)
@@ -2077,7 +2075,7 @@ private newtype TPathNode =
20772075
config.isSource(node) and
20782076
cc instanceof CallContextAny and
20792077
sc instanceof SummaryCtxNone and
2080-
ap = TNil(getErasedNodeTypeBound(node))
2078+
ap = TNil(getNodeType(node))
20812079
or
20822080
// ... or a step from an existing PathNode to another node.
20832081
exists(PathNodeMid mid |
@@ -2304,7 +2302,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
23042302
cc instanceof CallContextAny and
23052303
sc instanceof SummaryCtxNone and
23062304
mid.getAp() instanceof AccessPathNil and
2307-
ap = TNil(getErasedNodeTypeBound(node))
2305+
ap = TNil(getNodeType(node))
23082306
or
23092307
exists(TypedContent tc | pathStoreStep(mid, node, pop(tc, ap), tc, cc)) and
23102308
sc = mid.getSummaryCtx()
@@ -2646,7 +2644,7 @@ private module FlowExploration {
26462644
cc instanceof CallContextAny and
26472645
sc1 = TSummaryCtx1None() and
26482646
sc2 = TSummaryCtx2None() and
2649-
ap = TPartialNil(getErasedNodeTypeBound(node)) and
2647+
ap = TPartialNil(getNodeType(node)) and
26502648
not fullBarrier(node, config) and
26512649
exists(config.explorationLimit())
26522650
or
@@ -2663,7 +2661,7 @@ private module FlowExploration {
26632661
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
26642662
not fullBarrier(node, config) and
26652663
if node instanceof CastingNode
2666-
then compatibleTypes(getErasedNodeTypeBound(node), ap.getType())
2664+
then compatibleTypes(getNodeType(node), ap.getType())
26672665
else any()
26682666
)
26692667
}
@@ -2776,7 +2774,7 @@ private module FlowExploration {
27762774
sc1 = mid.getSummaryCtx1() and
27772775
sc2 = mid.getSummaryCtx2() and
27782776
mid.getAp() instanceof PartialAccessPathNil and
2779-
ap = TPartialNil(getErasedNodeTypeBound(node)) and
2777+
ap = TPartialNil(getNodeType(node)) and
27802778
config = mid.getConfiguration()
27812779
)
27822780
or
@@ -2792,7 +2790,7 @@ private module FlowExploration {
27922790
sc1 = TSummaryCtx1None() and
27932791
sc2 = TSummaryCtx2None() and
27942792
mid.getAp() instanceof PartialAccessPathNil and
2795-
ap = TPartialNil(getErasedNodeTypeBound(node)) and
2793+
ap = TPartialNil(getNodeType(node)) and
27962794
config = mid.getConfiguration()
27972795
or
27982796
partialPathStoreStep(mid, _, _, node, ap) and
@@ -2806,7 +2804,7 @@ private module FlowExploration {
28062804
sc1 = mid.getSummaryCtx1() and
28072805
sc2 = mid.getSummaryCtx2() and
28082806
apConsFwd(ap, tc, ap0, config) and
2809-
compatibleTypes(ap.getType(), getErasedNodeTypeBound(node))
2807+
compatibleTypes(ap.getType(), getNodeType(node))
28102808
)
28112809
or
28122810
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)

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

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ private module Cached {
2222
exists(int i |
2323
viableParam(call, i, p) and
2424
arg.argumentOf(call, i) and
25-
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(p))
25+
compatibleTypes(getNodeType(arg), getNodeType(p))
2626
)
2727
}
2828

@@ -218,10 +218,10 @@ private module Cached {
218218
then
219219
// normal flow through
220220
read = TReadStepTypesNone() and
221-
compatibleTypes(getErasedNodeTypeBound(p), getErasedNodeTypeBound(node))
221+
compatibleTypes(getNodeType(p), getNodeType(node))
222222
or
223223
// getter
224-
compatibleTypes(read.getContentType(), getErasedNodeTypeBound(node))
224+
compatibleTypes(read.getContentType(), getNodeType(node))
225225
else any()
226226
}
227227

@@ -243,7 +243,7 @@ private module Cached {
243243
readStepWithTypes(mid, read.getContainerType(), read.getContent(), node,
244244
read.getContentType()) and
245245
Cand::parameterValueFlowReturnCand(p, _, true) and
246-
compatibleTypes(getErasedNodeTypeBound(p), read.getContainerType())
246+
compatibleTypes(getNodeType(p), read.getContainerType())
247247
)
248248
or
249249
// flow through: no prior read
@@ -292,11 +292,11 @@ private module Cached {
292292
|
293293
// normal flow through
294294
read = TReadStepTypesNone() and
295-
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(out))
295+
compatibleTypes(getNodeType(arg), getNodeType(out))
296296
or
297297
// getter
298-
compatibleTypes(getErasedNodeTypeBound(arg), read.getContainerType()) and
299-
compatibleTypes(read.getContentType(), getErasedNodeTypeBound(out))
298+
compatibleTypes(getNodeType(arg), read.getContainerType()) and
299+
compatibleTypes(read.getContentType(), getNodeType(out))
300300
)
301301
}
302302

@@ -405,8 +405,8 @@ private module Cached {
405405
) {
406406
storeStep(node1, c, node2) and
407407
readStep(_, c, _) and
408-
contentType = getErasedNodeTypeBound(node1) and
409-
containerType = getErasedNodeTypeBound(node2)
408+
contentType = getNodeType(node1) and
409+
containerType = getNodeType(node2)
410410
or
411411
exists(Node n1, Node n2 |
412412
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
@@ -415,8 +415,8 @@ private module Cached {
415415
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
416416
or
417417
readStep(n2, c, n1) and
418-
contentType = getErasedNodeTypeBound(n1) and
419-
containerType = getErasedNodeTypeBound(n2)
418+
contentType = getNodeType(n1) and
419+
containerType = getNodeType(n2)
420420
)
421421
}
422422

@@ -507,8 +507,8 @@ private predicate readStepWithTypes(
507507
Node n1, DataFlowType container, Content c, Node n2, DataFlowType content
508508
) {
509509
readStep(n1, c, n2) and
510-
container = getErasedNodeTypeBound(n1) and
511-
content = getErasedNodeTypeBound(n2)
510+
container = getNodeType(n1) and
511+
content = getNodeType(n2)
512512
}
513513

514514
private newtype TReadStepTypesOption =
@@ -771,9 +771,6 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
771771
result = viableCallable(call) and cc instanceof CallContextReturn
772772
}
773773

774-
pragma[noinline]
775-
DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
776-
777774
predicate read = readStep/3;
778775

779776
/** An optional Boolean value. */

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,12 @@ module Consistency {
3737
)
3838
}
3939

40-
query predicate uniqueTypeBound(Node n, string msg) {
40+
query predicate uniqueType(Node n, string msg) {
4141
exists(int c |
4242
n instanceof RelevantNode and
43-
c = count(n.getTypeBound()) and
43+
c = count(getNodeType(n)) and
4444
c != 1 and
45-
msg = "Node should have one type bound but has " + c + "."
46-
)
47-
}
48-
49-
query predicate uniqueTypeRepr(Node n, string msg) {
50-
exists(int c |
51-
n instanceof RelevantNode and
52-
c = count(getErasedRepr(n.getTypeBound())) and
53-
c != 1 and
54-
msg = "Node should have one type representation but has " + c + "."
45+
msg = "Node should have one type but has " + c + "."
5546
)
5647
}
5748

@@ -104,7 +95,7 @@ module Consistency {
10495
msg = "Local flow step does not preserve enclosing callable."
10596
}
10697

107-
private DataFlowType typeRepr() { result = getErasedRepr(any(Node n).getTypeBound()) }
98+
private DataFlowType typeRepr() { result = getNodeType(_) }
10899

109100
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
110101
t = typeRepr() and

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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ abstract class NodeImpl extends Node {
2323
/** Do not call: use `getType()` instead. */
2424
abstract DotNet::Type getTypeImpl();
2525

26+
/** Gets the type of this node used for type pruning. */
27+
cached
28+
DataFlowType getDataFlowType() {
29+
Stages::DataFlowStage::forceCachingInSameStage() and
30+
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
31+
t0 = getCSharpType(this.getType())
32+
or
33+
not exists(getCSharpType(this.getType())) and
34+
t0 instanceof ObjectType
35+
)
36+
}
37+
2638
/** Do not call: use `getControlFlowNode()` instead. */
2739
abstract ControlFlow::Node getControlFlowNodeImpl();
2840

@@ -373,7 +385,7 @@ private predicate fieldOrPropertyRead(Expr e1, Content c, FieldOrPropertyRead e2
373385
)
374386
}
375387

376-
Type getCSharpType(DotNet::Type t) {
388+
private Type getCSharpType(DotNet::Type t) {
377389
result = t
378390
or
379391
result.matchesHandle(t)
@@ -1406,7 +1418,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
14061418
* Gets the predecessor of this library-code node. The head of `ap` describes
14071419
* the content that is read from when entering this node (if any).
14081420
*/
1409-
Node getPredecessor(AccessPath ap) {
1421+
NodeImpl getPredecessor(AccessPath ap) {
14101422
ap = sourceAp and
14111423
(
14121424
// The source is either an argument or a qualifier, for example
@@ -1430,7 +1442,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
14301442
* Gets the successor of this library-code node. The head of `ap` describes
14311443
* the content that is stored into when leaving this node (if any).
14321444
*/
1433-
Node getSuccessor(AccessPath ap) {
1445+
NodeImpl getSuccessor(AccessPath ap) {
14341446
ap = sinkAp and
14351447
(
14361448
exists(LibraryFlow::LibrarySinkConfiguration x, Call call, ExprNode e |
@@ -1482,18 +1494,18 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
14821494

14831495
override Callable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() }
14841496

1485-
override DataFlowType getTypeBound() {
1497+
override DataFlowType getDataFlowType() {
14861498
preservesValue = true and
14871499
sourceAp = AccessPath::empty() and
1488-
result = this.getPredecessor(_).getTypeBound()
1500+
result = this.getPredecessor(_).getDataFlowType()
14891501
or
14901502
exists(FieldOrProperty f |
14911503
sourceAp.getHead() = f.getContent() and
14921504
result = Gvn::getGlobalValueNumber(f.getType())
14931505
)
14941506
or
14951507
preservesValue = false and
1496-
result = this.getSuccessor(_).getTypeBound()
1508+
result = this.getSuccessor(_).getDataFlowType()
14971509
}
14981510

14991511
override DotNet::Type getTypeImpl() { none() }
@@ -1617,7 +1629,10 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
16171629

16181630
predicate readStep = readStepImpl/3;
16191631

1620-
/** Gets a string representation of a type returned by `getErasedRepr`. */
1632+
/** Gets the type of `n` used for type pruning. */
1633+
DataFlowType getNodeType(NodeImpl n) { result = n.getDataFlowType() }
1634+
1635+
/** Gets a string representation of a `DataFlowType`. */
16211636
string ppReprType(DataFlowType t) { result = t.toString() }
16221637

16231638
private class DataFlowNullType extends DataFlowType {
@@ -1794,9 +1809,6 @@ int accessPathLimit() { result = 3 }
17941809
*/
17951810
predicate isImmutableOrUnobservable(Node n) { none() }
17961811

1797-
pragma[inline]
1798-
DataFlowType getErasedRepr(DataFlowType t) { result = t }
1799-
18001812
/** Holds if `n` should be hidden from path explanations. */
18011813
predicate nodeIsHidden(Node n) {
18021814
exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() |

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,6 @@ class Node extends TNode {
4343
Stages::DataFlowStage::forceCachingInSameStage() and result = this.(NodeImpl).getTypeImpl()
4444
}
4545

46-
/** INTERNAL: Do not use. Gets an upper bound on the type of this node. */
47-
cached
48-
DataFlowType getTypeBound() {
49-
Stages::DataFlowStage::forceCachingInSameStage() and
50-
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
51-
t0 = getCSharpType(this.getType())
52-
or
53-
not exists(getCSharpType(this.getType())) and
54-
t0 instanceof ObjectType
55-
)
56-
}
57-
5846
/** Gets the enclosing callable of this node. */
5947
cached
6048
final DataFlowCallable getEnclosingCallable() {

0 commit comments

Comments
 (0)