diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index 8b9c8f5abd3..91f5aeacc9d 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -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] + DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) } + + pragma[noinline] + DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) } } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 7ecb474f632..9519a74265f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 8b9c8f5abd3..91f5aeacc9d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -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] + DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) } + + pragma[noinline] + DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 7ecb474f632..9519a74265f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 7ecb474f632..9519a74265f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 7ecb474f632..9519a74265f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 7ecb474f632..9519a74265f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 7ecb474f632..9519a74265f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index 8b9c8f5abd3..91f5aeacc9d 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -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] + DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) } + + pragma[noinline] + DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index d30ed00a0c4..9df3803fa3d 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1307,7 +1307,7 @@ private predicate suppressUnusedType(DotNet::Type t) { any() } * Type-based pruning is disabled for now, so this is a stub implementation. */ bindingset[t] -DotNet::Type getErasedRepr(DotNet::Type t) { +DataFlowType getErasedRepr(DotNet::Type t) { // stub implementation suppressUnusedType(t) and result instanceof ObjectType } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 7ecb474f632..9519a74265f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 7ecb474f632..9519a74265f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 7ecb474f632..9519a74265f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 7ecb474f632..9519a74265f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 7ecb474f632..9519a74265f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -464,7 +464,7 @@ private predicate simpleParameterFlow( ) { 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 @@ -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 DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path front for this node. */ AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) } @@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node { AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) } pragma[noinline] - private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) } + private DataFlowType getErasedReprType() { result = getErasedNodeType(this) } /** Gets the `nil` path for this node. */ AccessPathNil getAp() { result = TNil(this.getErasedReprType()) } @@ -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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index 8b9c8f5abd3..91f5aeacc9d 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -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] + DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) } + + pragma[noinline] + DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) } }