mirror of
https://github.com/github/codeql.git
synced 2026-04-19 05:54:00 +02:00
C#: Restrict DataFlowType to types belonging to Nodes
This commit is contained in:
@@ -26,7 +26,7 @@ abstract class NodeImpl extends Node {
|
||||
|
||||
/** Gets the type of this node used for type pruning. */
|
||||
cached
|
||||
DataFlowType getDataFlowType() {
|
||||
Gvn::GvnType getDataFlowType() {
|
||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
|
||||
t0 = getCSharpType(this.getType())
|
||||
@@ -490,14 +490,23 @@ private Type getCSharpType(DotNet::Type t) {
|
||||
result.matchesHandle(t)
|
||||
}
|
||||
|
||||
/** A GVN type that is either a `DataFlowType` or unifiable with a `DataFlowType`. */
|
||||
private class DataFlowTypeOrUnifiable extends Gvn::GvnType {
|
||||
pragma[nomagic]
|
||||
DataFlowTypeOrUnifiable() {
|
||||
this instanceof DataFlowType or
|
||||
Gvn::unifiable(any(DataFlowType t), this)
|
||||
}
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private TypeParameter getATypeParameterSubType(DataFlowType t) {
|
||||
private TypeParameter getATypeParameterSubType(DataFlowTypeOrUnifiable t) {
|
||||
not t instanceof Gvn::TypeParameterGvnType and
|
||||
exists(Type t0 | t = Gvn::getGlobalValueNumber(t0) | implicitConversionRestricted(result, t0))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private DataFlowType getANonTypeParameterSubType(DataFlowType t) {
|
||||
private Gvn::GvnType getANonTypeParameterSubType(DataFlowTypeOrUnifiable t) {
|
||||
not t instanceof Gvn::TypeParameterGvnType and
|
||||
not result instanceof Gvn::TypeParameterGvnType and
|
||||
exists(Type t1, Type t2 |
|
||||
@@ -728,12 +737,8 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if GVNs `t1` and `t2` may have a common sub type. Neither `t1` nor
|
||||
* `t2` are allowed to be type parameters.
|
||||
*/
|
||||
cached
|
||||
predicate commonSubType(DataFlowType t1, DataFlowType t2) {
|
||||
pragma[nomagic]
|
||||
private predicate commonSubTypeGeneral(DataFlowTypeOrUnifiable t1, DataFlowType t2) {
|
||||
not t1 instanceof Gvn::TypeParameterGvnType and
|
||||
t1 = t2
|
||||
or
|
||||
@@ -742,11 +747,18 @@ private module Cached {
|
||||
getANonTypeParameterSubType(t1) = getANonTypeParameterSubType(t2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if GVNs `t1` and `t2` may have a common sub type. Neither `t1` nor
|
||||
* `t2` are allowed to be type parameters.
|
||||
*/
|
||||
cached
|
||||
predicate commonSubType(DataFlowType t1, DataFlowType t2) { commonSubTypeGeneral(t1, t2) }
|
||||
|
||||
cached
|
||||
predicate commonSubTypeUnifiableLeft(DataFlowType t1, DataFlowType t2) {
|
||||
exists(DataFlowType t |
|
||||
exists(Gvn::GvnType t |
|
||||
Gvn::unifiable(t1, t) and
|
||||
commonSubType(t, t2)
|
||||
commonSubTypeGeneral(t, t2)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2004,7 +2016,7 @@ module LibraryFlow {
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
pragma[noinline]
|
||||
private DataFlowType getContentType(Content c) {
|
||||
private Gvn::GvnType getContentType(Content c) {
|
||||
exists(Type t | result = Gvn::getGlobalValueNumber(t) |
|
||||
t = c.(FieldContent).getField().getType()
|
||||
or
|
||||
@@ -2031,7 +2043,7 @@ class LibraryCodeNode extends NodeImpl, TLibraryCodeNode {
|
||||
|
||||
override Callable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() }
|
||||
|
||||
override DataFlowType getDataFlowType() {
|
||||
override Gvn::GvnType getDataFlowType() {
|
||||
exists(LibraryFlow::AdjustedAccessPath ap |
|
||||
state = LibraryFlow::TLibraryCodeNodeAfterReadState(ap) and
|
||||
if sinkAp.length() = 0 and state.isLastReadState() and preservesValue = true
|
||||
@@ -2194,6 +2206,20 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
|
||||
|
||||
predicate readStep = readStepImpl/3;
|
||||
|
||||
/**
|
||||
* An entity used to represent the type of data-flow node. Two nodes will have
|
||||
* the same `DataFlowType` when the underlying `Type`s are structurally equal
|
||||
* modulo type parameters and identity conversions.
|
||||
*
|
||||
* For example, `Func<T, int>` and `Func<S, int>` are mapped to the same
|
||||
* `DataFlowType`, while `Func<T, int>` and `Func<string, int>` are not, because
|
||||
* `string` is not a type parameter.
|
||||
*/
|
||||
class DataFlowType extends Gvn::GvnType {
|
||||
pragma[nomagic]
|
||||
DataFlowType() { this = any(NodeImpl n).getDataFlowType() }
|
||||
}
|
||||
|
||||
/** Gets the type of `n` used for type pruning. */
|
||||
DataFlowType getNodeType(NodeImpl n) { result = n.getDataFlowType() }
|
||||
|
||||
@@ -2323,8 +2349,6 @@ class CastNode extends Node {
|
||||
|
||||
class DataFlowExpr = DotNet::Expr;
|
||||
|
||||
class DataFlowType = Gvn::GvnType;
|
||||
|
||||
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
e = any(AbstractValues::BooleanValue bv | val = bv.getValue()).getAnExpr()
|
||||
|
||||
@@ -222,10 +222,10 @@ class Content extends TContent {
|
||||
Location getLocation() { none() }
|
||||
|
||||
/** Gets the type of the object containing this content. */
|
||||
deprecated DataFlowType getContainerType() { none() }
|
||||
deprecated Gvn::GvnType getContainerType() { none() }
|
||||
|
||||
/** Gets the type of this content. */
|
||||
deprecated DataFlowType getType() { none() }
|
||||
deprecated Gvn::GvnType getType() { none() }
|
||||
}
|
||||
|
||||
/** A reference to a field. */
|
||||
@@ -241,11 +241,11 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
override Location getLocation() { result = f.getLocation() }
|
||||
|
||||
deprecated override DataFlowType getContainerType() {
|
||||
deprecated override Gvn::GvnType getContainerType() {
|
||||
result = Gvn::getGlobalValueNumber(f.getDeclaringType())
|
||||
}
|
||||
|
||||
deprecated override DataFlowType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
|
||||
deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
|
||||
}
|
||||
|
||||
/** A reference to a property. */
|
||||
@@ -261,11 +261,11 @@ class PropertyContent extends Content, TPropertyContent {
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
deprecated override DataFlowType getContainerType() {
|
||||
deprecated override Gvn::GvnType getContainerType() {
|
||||
result = Gvn::getGlobalValueNumber(p.getDeclaringType())
|
||||
}
|
||||
|
||||
deprecated override DataFlowType getType() { result = Gvn::getGlobalValueNumber(p.getType()) }
|
||||
deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(p.getType()) }
|
||||
}
|
||||
|
||||
/** A reference to an element in a collection. */
|
||||
|
||||
Reference in New Issue
Block a user