diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 364359dc9fd..b14979470b0 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -215,19 +215,16 @@ predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } predicate localMustFlowStep(Node node1, Node node2) { none() } /** Gets the type of `n` used for type pruning. */ -Type getNodeType(Node n) { +DataFlowType getNodeType(Node n) { exists(n) and result instanceof VoidType // stub implementation } -/** Gets a string representation of a type returned by `getNodeType`. */ -string ppReprType(Type t) { none() } // stub implementation - /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. */ -predicate compatibleTypes(Type t1, Type t2) { +predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { t1 instanceof VoidType and t2 instanceof VoidType // stub implementation } @@ -243,7 +240,11 @@ class DataFlowCallable extends Function { } class DataFlowExpr = Expr; -class DataFlowType = Type; +final private class TypeFinal = Type; + +class DataFlowType extends TypeFinal { + string toString() { result = "" } +} /** A function call relevant for data flow. */ class DataFlowCall extends Expr instanceof Call { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 9381eb7f645..ac6e898748a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -994,9 +994,6 @@ DataFlowType getNodeType(Node n) { result instanceof VoidType // stub implementation } -/** Gets a string representation of a type returned by `getNodeType`. */ -string ppReprType(DataFlowType t) { none() } // stub implementation - /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. @@ -1097,7 +1094,11 @@ class SummarizedCallable extends DataFlowCallable, TSummarizedCallable { class DataFlowExpr = Expr; -class DataFlowType = Type; +final private class TypeFinal = Type; + +class DataFlowType extends TypeFinal { + string toString() { result = "" } +} cached private newtype TDataFlowCall = diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 4ad804e5049..d2307d62fe9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -2444,9 +2444,6 @@ DataFlowType getNodeType(Node n) { ] = result.getADelegateCreation() } -/** Gets a string representation of a `DataFlowType`. */ -string ppReprType(DataFlowType t) { result = t.toString() } - private class DataFlowNullType extends Gvn::GvnType { DataFlowNullType() { this = Gvn::getGlobalValueNumber(any(NullType nt)) } diff --git a/docs/ql-libraries/dataflow/dataflow.md b/docs/ql-libraries/dataflow/dataflow.md index 106c055eae0..ff7c71abfae 100644 --- a/docs/ql-libraries/dataflow/dataflow.md +++ b/docs/ql-libraries/dataflow/dataflow.md @@ -548,12 +548,9 @@ DataFlowType getNodeType(Node n) ``` and every `Node` should have a type. -One also needs to define the string representation of a `DataFlowType`: -```ql -string ppReprType(DataFlowType t) -``` -The `ppReprType` predicate is used for printing a type in the labels of -`PathNode`s, this can be defined as `none()` if type pruning is not used. +One also needs to define the string representation of a `DataFlowType`. +The `DataFlowType.toString` predicate is used for printing a type in the labels of +`PathNode`s, this should be defined as `result = ""` if type pruning is not used. Finally, one must define `CastNode` as a subclass of `Node` as those nodes where types should be checked. Usually this will be things like explicit casts. diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 2145fc41a05..2fcbf2d350f 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -215,9 +215,6 @@ predicate localMustFlowStep(Node node1, Node node2) { none() } /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(Node n) { result = TTodoDataFlowType() and exists(n) } -/** Gets a string representation of a type returned by `getNodeType()`. */ -string ppReprType(DataFlowType t) { none() } - /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index e455b8cdb4d..84b31f14e98 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -356,8 +356,12 @@ RefType getErasedRepr(Type t) { t instanceof NullType and result instanceof TypeObject } -class DataFlowType extends SrcRefType { +final private class SrcRefTypeFinal = SrcRefType; + +class DataFlowType extends SrcRefTypeFinal { DataFlowType() { this = getErasedRepr(_) } + + string toString() { result = ppReprType(this) } } pragma[nomagic] @@ -371,7 +375,7 @@ DataFlowType getNodeType(Node n) { } /** Gets a string representation of a type returned by `getErasedRepr`. */ -string ppReprType(DataFlowType t) { +private string ppReprType(SrcRefType t) { if t.(BoxedType).getPrimitiveType().getName() = "double" then result = "Number" else result = t.toString() diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 38436d99e14..218dbdae302 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -534,7 +534,7 @@ newtype TDataFlowType = TAnyFlow() class DataFlowType extends TDataFlowType { /** Gets a textual representation of this element. */ - string toString() { result = "DataFlowType" } + string toString() { result = "" } } /** A node that performs a type cast. */ @@ -578,9 +578,6 @@ DataFlowType getNodeType(Node node) { exists(node) } -/** Gets a string representation of a type returned by `getErasedRepr`. */ -string ppReprType(DataFlowType t) { none() } - //-------- // Extra flow //-------- diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 7bde4c8f9ac..6fef4d1222c 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -2077,9 +2077,6 @@ DataFlowType getNodeType(Node n) { result = TUnknownDataFlowType() } -/** Gets a string representation of a `DataFlowType`. */ -string ppReprType(DataFlowType t) { none() } - pragma[inline] private predicate compatibleTypesNonSymRefl(DataFlowType t1, DataFlowType t2) { t1 != TUnknownDataFlowType() and diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 6d6a08d3718..bbde158b8a6 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -124,8 +124,6 @@ signature module InputSig { string toString(); } - string ppReprType(DataFlowType t); - /** * Holds if `t1` and `t2` are compatible types. * diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index df081d02175..f293834d3d7 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -3445,9 +3445,11 @@ module MakeImpl Lang> { AccessPathApproxConsNil() { this = TConsNil(c, t) } + private string ppTyp() { result = t.toString() and result != "" } + override string toString() { - // The `concat` becomes "" if `ppReprType` has no result. - result = "[" + c.toString() + "]" + concat(" : " + ppReprType(t)) + // The `concat` becomes "" if `ppTyp` has no result. + result = "[" + c.toString() + "]" + concat(" : " + this.ppTyp()) } override Content getHead() { result = c } @@ -3668,7 +3670,9 @@ module MakeImpl Lang> { ParamNodeEx getParamNode() { result = p } - override string toString() { result = p + concat(" : " + ppReprType(t)) + " " + ap } + private string ppTyp() { result = t.toString() and result != "" } + + override string toString() { result = p + concat(" : " + this.ppTyp()) + " " + ap } Location getLocation() { result = p.getLocation() } } @@ -3935,10 +3939,12 @@ module MakeImpl Lang> { override int length() { result = 1 + tail_.length() } + private string ppTyp() { result = t.toString() and result != "" } + private string toStringImpl(boolean needsSuffix) { tail_ = TAccessPathNil() and needsSuffix = false and - result = head_.toString() + "]" + concat(" : " + ppReprType(t)) + result = head_.toString() + "]" + concat(" : " + this.ppTyp()) or result = head_ + ", " + tail_.(AccessPathCons).toStringImpl(needsSuffix) or @@ -4087,9 +4093,8 @@ module MakeImpl Lang> { private string ppType() { this instanceof PathNodeSink and result = "" or - exists(DataFlowType t | t = this.(PathNodeMid).getType() | - // The `concat` becomes "" if `ppReprType` has no result. - result = concat(" : " + ppReprType(t)) + exists(string t | t = this.(PathNodeMid).getType().toString() | + if t = "" then result = "" else result = " : " + t ) } @@ -5402,9 +5407,8 @@ module MakeImpl Lang> { private string ppType() { this instanceof PartialPathNodeRev and result = "" or - exists(DataFlowType t | t = this.(PartialPathNodeFwd).getType() | - // The `concat` becomes "" if `ppReprType` has no result. - result = concat(" : " + ppReprType(t)) + exists(string t | t = this.(PartialPathNodeFwd).getType().toString() | + if t = "" then result = "" else result = " : " + t ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 5abc652b3b4..c84298771fb 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -1310,9 +1310,6 @@ DataFlowType getNodeType(Node n) { any() // return the singleton DataFlowType until we support type pruning for Swift } -/** Gets a string representation of a `DataFlowType`. */ -string ppReprType(DataFlowType t) { none() } - /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`.