mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Data flow: Sync files
This commit is contained in:
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -57,14 +57,14 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowCand(p, mid) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(Node arg |
|
||||
parameterValueFlowCand(p, arg) and
|
||||
argumentValueFlowsThroughCand(arg, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ private module ImplCommon {
|
||||
argumentValueFlowsThroughCand0(call, arg, kind)
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlow(p, mid, cc) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
or
|
||||
@@ -191,7 +191,7 @@ private module ImplCommon {
|
||||
exists(Node arg |
|
||||
parameterValueFlow(p, arg, cc) and
|
||||
argumentValueFlowsThrough(arg, node, cc) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
}
|
||||
@@ -226,7 +226,7 @@ private module ImplCommon {
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -260,7 +260,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowNoCtx(p, mid) and
|
||||
localValueStep(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -296,8 +296,8 @@ private module ImplCommon {
|
||||
setterCall(call, i1, i2, f) and
|
||||
node1.(ArgumentNode).argumentOf(call, i1) and
|
||||
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getContainerType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -333,8 +333,8 @@ private module ImplCommon {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
storeReturn0(call, kind, node1, f) and
|
||||
node2 = getAnOutNode(call, kind) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getContainerType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -365,8 +365,8 @@ private module ImplCommon {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
read0(call, kind, node1, f) and
|
||||
node2 = getAnOutNode(call, kind) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ private module ImplCommon {
|
||||
store(node1, f, mid1) and
|
||||
localValueStep*(mid1, mid2) and
|
||||
read(mid2, f, node2) and
|
||||
compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -405,14 +405,14 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowCand(p, mid) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(Node arg |
|
||||
parameterValueFlowCand(p, arg) and
|
||||
argumentValueFlowsThroughCand(arg, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ private module ImplCommon {
|
||||
argumentValueFlowsThroughCand0(call, arg, kind)
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlow(p, mid, cc) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
or
|
||||
@@ -539,7 +539,7 @@ private module ImplCommon {
|
||||
exists(Node arg |
|
||||
parameterValueFlow(p, arg, cc) and
|
||||
argumentValueFlowsThrough(arg, node, cc) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
}
|
||||
@@ -574,7 +574,7 @@ private module ImplCommon {
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -860,4 +860,10 @@ private module ImplCommon {
|
||||
or
|
||||
result = viableCallable(call) and cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
|
||||
|
||||
pragma[noinline]
|
||||
DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
|
||||
}
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate simpleParameterFlow(
|
||||
ParameterNode p, Node node, DataFlowType t, Configuration config
|
||||
ParameterNode p, Node node, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
throughFlowNodeCand(node, config) and
|
||||
p = node and
|
||||
t = getErasedRepr(node.getType()) and
|
||||
t = getErasedNodeType(node) and
|
||||
exists(ReturnNode ret, ReturnKind kind |
|
||||
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localFlowStep(mid, node, config) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, _, config) and
|
||||
additionalLocalFlowStep(mid, node, config) and
|
||||
t = getErasedRepr(node.getType())
|
||||
t = getErasedNodeType(node)
|
||||
)
|
||||
or
|
||||
throughFlowNodeCand(node, unbind(config)) and
|
||||
exists(Node mid |
|
||||
simpleParameterFlow(p, mid, t, config) and
|
||||
localStoreReadStep(mid, node) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// value flow through a callable
|
||||
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
|
||||
exists(Node arg |
|
||||
simpleParameterFlow(p, arg, t, config) and
|
||||
argumentValueFlowsThrough(arg, node, _) and
|
||||
compatibleTypes(t, node.getType())
|
||||
compatibleTypes(t, getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
|
||||
|
||||
pragma[noinline]
|
||||
private predicate simpleArgumentFlowsThrough0(
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
|
||||
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
nodeCand1(arg, unbind(config)) and
|
||||
not outBarrier(arg, config) and
|
||||
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
|
||||
* additional step from the configuration.
|
||||
*/
|
||||
private predicate simpleArgumentFlowsThrough(
|
||||
ArgumentNode arg, Node out, DataFlowType t, Configuration config
|
||||
ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
nodeCand1(out, unbind(config)) and
|
||||
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
|
||||
}
|
||||
|
||||
private newtype TAccessPathFront =
|
||||
TFrontNil(DataFlowType t) or
|
||||
TFrontNil(DataFlowErasedType t) or
|
||||
TFrontHead(Content f)
|
||||
|
||||
/**
|
||||
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
|
||||
*/
|
||||
private class AccessPathFront extends TAccessPathFront {
|
||||
string toString() {
|
||||
exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
|
||||
or
|
||||
exists(Content f | this = TFrontHead(f) | result = f.toString())
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TFrontNil(result)
|
||||
or
|
||||
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
|
||||
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
|
||||
*/
|
||||
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
|
||||
flowCandFwd0(node, fromArg, apf, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), apf.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path front for this node. */
|
||||
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
|
||||
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
|
||||
flowCandFwd(mid, fromArg, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
apf = TFrontNil(t)
|
||||
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
|
||||
}
|
||||
|
||||
private newtype TAccessPath =
|
||||
TNil(DataFlowType t) or
|
||||
TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TNil(DataFlowErasedType t) or
|
||||
TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
this = TConsCons(_, _, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TNil(result)
|
||||
or
|
||||
result = this.getHead().getContainerType()
|
||||
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) { none() }
|
||||
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
|
||||
|
||||
private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
}
|
||||
|
||||
override predicate pop(Content head, AccessPath tail) {
|
||||
exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
|
||||
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
|
||||
private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
|
||||
|
||||
/** Gets the `nil` path for this node. */
|
||||
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
|
||||
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
|
||||
argumentValueFlowsThrough(mid, node, _)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil, DataFlowType t |
|
||||
exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
|
||||
flowFwd(mid, fromArg, _, nil, config) and
|
||||
simpleArgumentFlowsThrough(mid, node, t, config) and
|
||||
ap = TNil(t) and
|
||||
@@ -2018,7 +2020,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private newtype TPartialAccessPath =
|
||||
TPartialNil(DataFlowType t) or
|
||||
TPartialNil(DataFlowErasedType t) or
|
||||
TPartialCons(Content f, int len) { len in [1 .. 5] }
|
||||
|
||||
/**
|
||||
@@ -2039,7 +2041,7 @@ private module FlowExploration {
|
||||
this = TPartialCons(_, result)
|
||||
}
|
||||
|
||||
DataFlowType getType() {
|
||||
DataFlowErasedType getType() {
|
||||
this = TPartialNil(result)
|
||||
or
|
||||
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
|
||||
@@ -2050,11 +2052,11 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2076,7 +2078,7 @@ private module FlowExploration {
|
||||
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -2091,7 +2093,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNode mid |
|
||||
partialPathStep(mid, node, cc, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getErasedNodeType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2194,7 +2198,7 @@ private module FlowExploration {
|
||||
additionalLocalFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -2206,7 +2210,7 @@ private module FlowExploration {
|
||||
additionalJumpStep(mid.getNode(), node, config) and
|
||||
cc instanceof CallContextAny and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getErasedRepr(node.getType())) and
|
||||
ap = TPartialNil(getErasedNodeType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
|
||||
@@ -57,14 +57,14 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowCand(p, mid) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(Node arg |
|
||||
parameterValueFlowCand(p, arg) and
|
||||
argumentValueFlowsThroughCand(arg, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ private module ImplCommon {
|
||||
argumentValueFlowsThroughCand0(call, arg, kind)
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlow(p, mid, cc) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
or
|
||||
@@ -191,7 +191,7 @@ private module ImplCommon {
|
||||
exists(Node arg |
|
||||
parameterValueFlow(p, arg, cc) and
|
||||
argumentValueFlowsThrough(arg, node, cc) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
}
|
||||
@@ -226,7 +226,7 @@ private module ImplCommon {
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -260,7 +260,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowNoCtx(p, mid) and
|
||||
localValueStep(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -296,8 +296,8 @@ private module ImplCommon {
|
||||
setterCall(call, i1, i2, f) and
|
||||
node1.(ArgumentNode).argumentOf(call, i1) and
|
||||
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getContainerType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -333,8 +333,8 @@ private module ImplCommon {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
storeReturn0(call, kind, node1, f) and
|
||||
node2 = getAnOutNode(call, kind) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getContainerType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -365,8 +365,8 @@ private module ImplCommon {
|
||||
exists(DataFlowCall call, ReturnKind kind |
|
||||
read0(call, kind, node1, f) and
|
||||
node2 = getAnOutNode(call, kind) and
|
||||
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
|
||||
compatibleTypes(node2.getTypeBound(), f.getType())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
|
||||
compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ private module ImplCommon {
|
||||
store(node1, f, mid1) and
|
||||
localValueStep*(mid1, mid2) and
|
||||
read(mid2, f, node2) and
|
||||
compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
|
||||
compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -405,14 +405,14 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlowCand(p, mid) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(Node arg |
|
||||
parameterValueFlowCand(p, arg) and
|
||||
argumentValueFlowsThroughCand(arg, node) and
|
||||
compatibleTypes(p.getType(), node.getType())
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ private module ImplCommon {
|
||||
argumentValueFlowsThroughCand0(call, arg, kind)
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ private module ImplCommon {
|
||||
exists(Node mid |
|
||||
parameterValueFlow(p, mid, cc) and
|
||||
step(mid, node) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
or
|
||||
@@ -539,7 +539,7 @@ private module ImplCommon {
|
||||
exists(Node arg |
|
||||
parameterValueFlow(p, arg, cc) and
|
||||
argumentValueFlowsThrough(arg, node, cc) and
|
||||
compatibleTypes(p.getType(), node.getType()) and
|
||||
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
|
||||
)
|
||||
}
|
||||
@@ -574,7 +574,7 @@ private module ImplCommon {
|
||||
|
|
||||
out = getAnOutNode(call, kind) and
|
||||
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
|
||||
compatibleTypes(arg.getType(), out.getType())
|
||||
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -860,4 +860,10 @@ private module ImplCommon {
|
||||
or
|
||||
result = viableCallable(call) and cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
|
||||
|
||||
pragma[noinline]
|
||||
DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user