mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
C#: Replace getErasedRepr() and getTypeBound() with getNodeType()
This commit is contained in:
@@ -68,7 +68,7 @@ module Stages {
|
||||
or
|
||||
exists(any(DataFlow::Node n).getType())
|
||||
or
|
||||
exists(any(DataFlow::Node n).getTypeBound())
|
||||
exists(any(NodeImpl n).getDataFlowType())
|
||||
or
|
||||
exists(any(DataFlow::Node n).getLocation())
|
||||
or
|
||||
|
||||
@@ -1124,11 +1124,11 @@ private module LocalFlowBigStep {
|
||||
(
|
||||
localFlowStepNodeCand1(node1, node2, config) and
|
||||
preservesValue = true and
|
||||
t = getErasedNodeTypeBound(node1)
|
||||
t = getNodeType(node1)
|
||||
or
|
||||
additionalLocalFlowStepNodeCand2(node1, node2, config) and
|
||||
preservesValue = false and
|
||||
t = getErasedNodeTypeBound(node2)
|
||||
t = getNodeType(node2)
|
||||
) and
|
||||
node1 != node2 and
|
||||
cc.relevantFor(node1.getEnclosingCallable()) and
|
||||
@@ -1147,7 +1147,7 @@ private module LocalFlowBigStep {
|
||||
additionalLocalFlowStepNodeCand2(mid, node2, config) and
|
||||
not mid instanceof FlowCheckNode and
|
||||
preservesValue = false and
|
||||
t = getErasedNodeTypeBound(node2) and
|
||||
t = getNodeType(node2) and
|
||||
nodeCand2(node2, unbind(config))
|
||||
)
|
||||
)
|
||||
@@ -1202,9 +1202,7 @@ private predicate flowCandFwd(
|
||||
) {
|
||||
flowCandFwd0(node, fromArg, argApf, apf, config) and
|
||||
not apf.isClearedAt(node) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeTypeBound(node), apf.getType())
|
||||
else any()
|
||||
if node instanceof CastingNode then compatibleTypes(getNodeType(node), apf.getType()) else any()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -1216,7 +1214,7 @@ private predicate flowCandFwd0(
|
||||
config.isSource(node) and
|
||||
fromArg = false and
|
||||
argApf = TAccessPathFrontNone() and
|
||||
apf = TFrontNil(getErasedNodeTypeBound(node))
|
||||
apf = TFrontNil(getNodeType(node))
|
||||
or
|
||||
exists(Node mid |
|
||||
flowCandFwd(mid, fromArg, argApf, apf, config) and
|
||||
@@ -1242,7 +1240,7 @@ private predicate flowCandFwd0(
|
||||
additionalJumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
argApf = TAccessPathFrontNone() and
|
||||
apf = TFrontNil(getErasedNodeTypeBound(node))
|
||||
apf = TFrontNil(getNodeType(node))
|
||||
)
|
||||
or
|
||||
// store
|
||||
@@ -1672,7 +1670,7 @@ private predicate flowFwd0(
|
||||
config.isSource(node) and
|
||||
fromArg = false and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getErasedNodeTypeBound(node)) and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
or
|
||||
flowCand(node, _, _, _, unbind(config)) and
|
||||
@@ -1700,7 +1698,7 @@ private predicate flowFwd0(
|
||||
additionalJumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getErasedNodeTypeBound(node)) and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
)
|
||||
)
|
||||
@@ -2077,7 +2075,7 @@ private newtype TPathNode =
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TNil(getErasedNodeTypeBound(node))
|
||||
ap = TNil(getNodeType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
@@ -2304,7 +2302,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
ap = TNil(getErasedNodeTypeBound(node))
|
||||
ap = TNil(getNodeType(node))
|
||||
or
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, pop(tc, ap), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
@@ -2646,7 +2644,7 @@ private module FlowExploration {
|
||||
cc instanceof CallContextAny and
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
ap = TPartialNil(getErasedNodeTypeBound(node)) and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2663,7 +2661,7 @@ private module FlowExploration {
|
||||
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeTypeBound(node), ap.getType())
|
||||
then compatibleTypes(getNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
@@ -2776,7 +2774,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedNodeTypeBound(node)) and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2792,7 +2790,7 @@ private module FlowExploration {
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedNodeTypeBound(node)) and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
@@ -2806,7 +2804,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
apConsFwd(ap, tc, ap0, config) and
|
||||
compatibleTypes(ap.getType(), getErasedNodeTypeBound(node))
|
||||
compatibleTypes(ap.getType(), getNodeType(node))
|
||||
)
|
||||
or
|
||||
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
|
||||
|
||||
@@ -22,7 +22,7 @@ private module Cached {
|
||||
exists(int i |
|
||||
viableParam(call, i, p) and
|
||||
arg.argumentOf(call, i) and
|
||||
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(p))
|
||||
compatibleTypes(getNodeType(arg), getNodeType(p))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -218,10 +218,10 @@ private module Cached {
|
||||
then
|
||||
// normal flow through
|
||||
read = TReadStepTypesNone() and
|
||||
compatibleTypes(getErasedNodeTypeBound(p), getErasedNodeTypeBound(node))
|
||||
compatibleTypes(getNodeType(p), getNodeType(node))
|
||||
or
|
||||
// getter
|
||||
compatibleTypes(read.getContentType(), getErasedNodeTypeBound(node))
|
||||
compatibleTypes(read.getContentType(), getNodeType(node))
|
||||
else any()
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ private module Cached {
|
||||
readStepWithTypes(mid, read.getContainerType(), read.getContent(), node,
|
||||
read.getContentType()) and
|
||||
Cand::parameterValueFlowReturnCand(p, _, true) and
|
||||
compatibleTypes(getErasedNodeTypeBound(p), read.getContainerType())
|
||||
compatibleTypes(getNodeType(p), read.getContainerType())
|
||||
)
|
||||
or
|
||||
// flow through: no prior read
|
||||
@@ -292,11 +292,11 @@ private module Cached {
|
||||
|
|
||||
// normal flow through
|
||||
read = TReadStepTypesNone() and
|
||||
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(out))
|
||||
compatibleTypes(getNodeType(arg), getNodeType(out))
|
||||
or
|
||||
// getter
|
||||
compatibleTypes(getErasedNodeTypeBound(arg), read.getContainerType()) and
|
||||
compatibleTypes(read.getContentType(), getErasedNodeTypeBound(out))
|
||||
compatibleTypes(getNodeType(arg), read.getContainerType()) and
|
||||
compatibleTypes(read.getContentType(), getNodeType(out))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -405,8 +405,8 @@ private module Cached {
|
||||
) {
|
||||
storeStep(node1, c, node2) and
|
||||
readStep(_, c, _) and
|
||||
contentType = getErasedNodeTypeBound(node1) and
|
||||
containerType = getErasedNodeTypeBound(node2)
|
||||
contentType = getNodeType(node1) and
|
||||
containerType = getNodeType(node2)
|
||||
or
|
||||
exists(Node n1, Node n2 |
|
||||
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
|
||||
@@ -415,8 +415,8 @@ private module Cached {
|
||||
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
|
||||
or
|
||||
readStep(n2, c, n1) and
|
||||
contentType = getErasedNodeTypeBound(n1) and
|
||||
containerType = getErasedNodeTypeBound(n2)
|
||||
contentType = getNodeType(n1) and
|
||||
containerType = getNodeType(n2)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -507,8 +507,8 @@ private predicate readStepWithTypes(
|
||||
Node n1, DataFlowType container, Content c, Node n2, DataFlowType content
|
||||
) {
|
||||
readStep(n1, c, n2) and
|
||||
container = getErasedNodeTypeBound(n1) and
|
||||
content = getErasedNodeTypeBound(n2)
|
||||
container = getNodeType(n1) and
|
||||
content = getNodeType(n2)
|
||||
}
|
||||
|
||||
private newtype TReadStepTypesOption =
|
||||
@@ -771,9 +771,6 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
result = viableCallable(call) and cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
|
||||
|
||||
predicate read = readStep/3;
|
||||
|
||||
/** An optional Boolean value. */
|
||||
|
||||
@@ -37,21 +37,12 @@ module Consistency {
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueTypeBound(Node n, string msg) {
|
||||
query predicate uniqueType(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(n.getTypeBound()) and
|
||||
c = count(getNodeType(n)) and
|
||||
c != 1 and
|
||||
msg = "Node should have one type bound but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueTypeRepr(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(getErasedRepr(n.getTypeBound())) and
|
||||
c != 1 and
|
||||
msg = "Node should have one type representation but has " + c + "."
|
||||
msg = "Node should have one type but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
@@ -104,7 +95,7 @@ module Consistency {
|
||||
msg = "Local flow step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
private DataFlowType typeRepr() { result = getErasedRepr(any(Node n).getTypeBound()) }
|
||||
private DataFlowType typeRepr() { result = getNodeType(_) }
|
||||
|
||||
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
|
||||
t = typeRepr() and
|
||||
|
||||
@@ -23,6 +23,18 @@ abstract class NodeImpl extends Node {
|
||||
/** Do not call: use `getType()` instead. */
|
||||
abstract DotNet::Type getTypeImpl();
|
||||
|
||||
/** Gets the type of this node used for type pruning. */
|
||||
cached
|
||||
DataFlowType getDataFlowType() {
|
||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
|
||||
t0 = getCSharpType(this.getType())
|
||||
or
|
||||
not exists(getCSharpType(this.getType())) and
|
||||
t0 instanceof ObjectType
|
||||
)
|
||||
}
|
||||
|
||||
/** Do not call: use `getControlFlowNode()` instead. */
|
||||
abstract ControlFlow::Node getControlFlowNodeImpl();
|
||||
|
||||
@@ -373,7 +385,7 @@ private predicate fieldOrPropertyRead(Expr e1, Content c, FieldOrPropertyRead e2
|
||||
)
|
||||
}
|
||||
|
||||
Type getCSharpType(DotNet::Type t) {
|
||||
private Type getCSharpType(DotNet::Type t) {
|
||||
result = t
|
||||
or
|
||||
result.matchesHandle(t)
|
||||
@@ -1406,7 +1418,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
|
||||
* Gets the predecessor of this library-code node. The head of `ap` describes
|
||||
* the content that is read from when entering this node (if any).
|
||||
*/
|
||||
Node getPredecessor(AccessPath ap) {
|
||||
NodeImpl getPredecessor(AccessPath ap) {
|
||||
ap = sourceAp and
|
||||
(
|
||||
// The source is either an argument or a qualifier, for example
|
||||
@@ -1430,7 +1442,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
|
||||
* Gets the successor of this library-code node. The head of `ap` describes
|
||||
* the content that is stored into when leaving this node (if any).
|
||||
*/
|
||||
Node getSuccessor(AccessPath ap) {
|
||||
NodeImpl getSuccessor(AccessPath ap) {
|
||||
ap = sinkAp and
|
||||
(
|
||||
exists(LibraryFlow::LibrarySinkConfiguration x, Call call, ExprNode e |
|
||||
@@ -1482,10 +1494,10 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
|
||||
|
||||
override Callable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() }
|
||||
|
||||
override DataFlowType getTypeBound() {
|
||||
override DataFlowType getDataFlowType() {
|
||||
preservesValue = true and
|
||||
sourceAp = AccessPath::empty() and
|
||||
result = this.getPredecessor(_).getTypeBound()
|
||||
result = this.getPredecessor(_).getDataFlowType()
|
||||
or
|
||||
exists(FieldOrProperty f |
|
||||
sourceAp.getHead() = f.getContent() and
|
||||
@@ -1493,7 +1505,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
|
||||
)
|
||||
or
|
||||
preservesValue = false and
|
||||
result = this.getSuccessor(_).getTypeBound()
|
||||
result = this.getSuccessor(_).getDataFlowType()
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
@@ -1617,7 +1629,10 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
|
||||
|
||||
predicate readStep = readStepImpl/3;
|
||||
|
||||
/** Gets a string representation of a type returned by `getErasedRepr`. */
|
||||
/** Gets the type of `n` used for type pruning. */
|
||||
DataFlowType getNodeType(NodeImpl n) { result = n.getDataFlowType() }
|
||||
|
||||
/** Gets a string representation of a `DataFlowType`. */
|
||||
string ppReprType(DataFlowType t) { result = t.toString() }
|
||||
|
||||
private class DataFlowNullType extends DataFlowType {
|
||||
@@ -1794,9 +1809,6 @@ int accessPathLimit() { result = 3 }
|
||||
*/
|
||||
predicate isImmutableOrUnobservable(Node n) { none() }
|
||||
|
||||
pragma[inline]
|
||||
DataFlowType getErasedRepr(DataFlowType t) { result = t }
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) {
|
||||
exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() |
|
||||
|
||||
@@ -43,18 +43,6 @@ class Node extends TNode {
|
||||
Stages::DataFlowStage::forceCachingInSameStage() and result = this.(NodeImpl).getTypeImpl()
|
||||
}
|
||||
|
||||
/** INTERNAL: Do not use. Gets an upper bound on the type of this node. */
|
||||
cached
|
||||
DataFlowType getTypeBound() {
|
||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
|
||||
t0 = getCSharpType(this.getType())
|
||||
or
|
||||
not exists(getCSharpType(this.getType())) and
|
||||
t0 instanceof ObjectType
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the enclosing callable of this node. */
|
||||
cached
|
||||
final DataFlowCallable getEnclosingCallable() {
|
||||
|
||||
Reference in New Issue
Block a user