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 7a44432965cb..a2de9888e515 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 @@ -1061,6 +1061,16 @@ class DataFlowCallable extends TDataFlowCallable { result = this.asSummarizedCallable() or // SummarizedCallable = Function (in CPP) result = this.asSourceCallable() } + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, string file, int startline, int startcolumn | + c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _) + | + c order by file, startline, startcolumn + ) + } } /** @@ -1267,6 +1277,15 @@ module IsUnreachableInCall { string toString() { result = "NodeRegion" } predicate contains(Node n) { this = n.getBasicBlock() } + + int totalOrder() { + this = + rank[result](IRBlock b, int startline, int startcolumn | + b.getLocation().hasLocationInfo(_, startline, startcolumn, _, _) + | + b order by startline, startcolumn + ) + } } predicate isUnreachableInCall(NodeRegion block, DataFlowCall call) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index fd9c5e272061..369786498f7e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -318,6 +318,16 @@ class DataFlowCallable extends TDataFlowCallable { result = this.asFileScope().getLocation() or result = getCallableLocation(this.asSummarizedCallable()) } + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, string file, int startline, int startcolumn | + c.hasLocationInfo(file, startline, startcolumn, _, _) + | + c order by file, startline, startcolumn + ) + } } private Location getCallableLocation(Callable c) { @@ -410,6 +420,15 @@ class NodeRegion instanceof BasicBlock { string toString() { result = "NodeRegion" } predicate contains(Node n) { n.getBasicBlock() = this } + + int totalOrder() { + this = + rank[result](BasicBlock b, int startline, int startcolumn | + b.hasLocationInfo(_, startline, startcolumn, _, _) + | + b order by startline, startcolumn + ) + } } /** 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 a380cb30402a..8caacbf0c135 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -412,6 +412,21 @@ predicate cloneStep(Node n1, Node n2) { bindingset[node1, node2] predicate validParameterAliasStep(Node node1, Node node2) { not cloneStep(node1, node2) } +private predicate id_member(Member x, Member y) { x = y } + +private predicate idOf_member(Member x, int y) = equivalenceRelation(id_member/2)(x, y) + +private int summarizedCallableId(SummarizedCallable c) { + c = + rank[result](SummarizedCallable c0, int b, int i, string s | + b = 0 and idOf_member(c0.asCallable(), i) and s = "" + or + b = 1 and i = 0 and s = c0.asSyntheticCallable() + | + c0 order by b, i, s + ) +} + private newtype TDataFlowCallable = TSrcCallable(Callable c) or TSummarizedCallable(SummarizedCallable c) or @@ -445,10 +460,28 @@ class DataFlowCallable extends TDataFlowCallable { result = this.asSummarizedCallable().getLocation() or result = this.asFieldScope().getLocation() } + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, int b, int i | + b = 0 and idOf_member(c.asCallable(), i) + or + b = 1 and i = summarizedCallableId(c.asSummarizedCallable()) + or + b = 2 and idOf_member(c.asFieldScope(), i) + | + c order by b, i + ) + } } class DataFlowExpr = Expr; +private predicate id_call(Call x, Call y) { x = y } + +private predicate idOf_call(Call x, int y) = equivalenceRelation(id_call/2)(x, y) + private newtype TDataFlowCall = TCall(Call c) or TSummaryCall(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) { @@ -538,10 +571,16 @@ class SummaryCall extends DataFlowCall, TSummaryCall { override Location getLocation() { result = c.getLocation() } } +private predicate id(BasicBlock x, BasicBlock y) { x = y } + +private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) + class NodeRegion instanceof BasicBlock { string toString() { result = "NodeRegion" } predicate contains(Node n) { n.asExpr().getBasicBlock() = this } + + int totalOrder() { idOf(this, result) } } /** Holds if `e` is an expression that always has the same Boolean value `val`. */ diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 805960347cfa..afbcacec6369 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -344,6 +344,16 @@ abstract class DataFlowCallable extends TDataFlowCallable { /** Gets the location of this dataflow callable. */ abstract Location getLocation(); + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, string file, int startline, int startcolumn | + c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _) + | + c order by file, startline, startcolumn + ) + } } /** A callable function. */ 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 38436d99e147..5b9b6c1a3273 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1025,6 +1025,8 @@ class NodeRegion instanceof Unit { string toString() { result = "NodeRegion" } predicate contains(Node n) { none() } + + int totalOrder() { result = 1 } } //-------- diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index bc7782e2d9da..9a426eea323e 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -113,6 +113,16 @@ class DataFlowCallable extends TDataFlowCallable { this instanceof TLibraryCallable and result instanceof EmptyLocation } + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, string file, int startline, int startcolumn | + c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _) + | + c order by file, startline, startcolumn + ) + } } /** diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 7bde4c8f9ac9..c0bc6ac243d7 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -2183,6 +2183,8 @@ class NodeRegion instanceof Unit { string toString() { result = "NodeRegion" } predicate contains(Node n) { none() } + + int totalOrder() { result = 1 } } /** diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 36bd9596ec2f..680981ddb31f 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -97,6 +97,9 @@ signature module InputSig { /** Gets the location of this callable. */ Location getLocation(); + + /** Gets a best-effort total ordering. */ + int totalorder(); } class ReturnKind { @@ -273,6 +276,8 @@ signature module InputSig { class NodeRegion { /** Holds if this region contains `n`. */ predicate contains(Node n); + + int totalOrder(); } /** diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 687eb00d1efc..915334031169 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -65,6 +65,16 @@ class DataFlowCallable extends TDataFlowCallable { Callable::TypeRange getUnderlyingCallable() { result = this.asSummarizedCallable() or result = this.asSourceCallable() } + + /** Gets a best-effort total ordering. */ + int totalorder() { + this = + rank[result](DataFlowCallable c, string file, int startline, int startcolumn | + c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _) + | + c order by file, startline, startcolumn + ) + } } cached diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 5abc652b3b44..de54324e005b 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -1381,6 +1381,8 @@ class NodeRegion instanceof Unit { string toString() { result = "NodeRegion" } predicate contains(Node n) { none() } + + int totalOrder() { result = 1 } } /**