diff --git a/config/identical-files.json b/config/identical-files.json
index 214fc402c4f..f814b0f1f81 100644
--- a/config/identical-files.json
+++ b/config/identical-files.json
@@ -55,15 +55,6 @@
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
],
- "DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [
- "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
- "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
- "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
- "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
- "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll",
- "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll",
- "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll"
- ],
"DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
@@ -561,4 +552,4 @@
"python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml",
"python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml"
]
-}
+}
\ No newline at end of file
diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj
index abf4f358a24..0c9f70c6d6d 100644
--- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj
+++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj
@@ -11,12 +11,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers
-
+
diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj
index 5e0d40cdfe2..f8f5c285074 100644
--- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj
+++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md
index 2bdc935dfac..58c1d800b3d 100644
--- a/cpp/ql/lib/CHANGELOG.md
+++ b/cpp/ql/lib/CHANGELOG.md
@@ -1,3 +1,18 @@
+## 0.9.2
+
+### Deprecated APIs
+
+* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead.
+
+### New Features
+
+* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr`
+
+### Minor Analysis Improvements
+
+* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation.
+* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
+
## 0.9.1
No user-facing changes.
diff --git a/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md b/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md
deleted file mode 100644
index 4baf9b770d6..00000000000
--- a/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
diff --git a/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md b/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md
deleted file mode 100644
index f3f3a59e8f0..00000000000
--- a/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: feature
----
-* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr`
\ No newline at end of file
diff --git a/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md b/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md
deleted file mode 100644
index b9bb1fada5b..00000000000
--- a/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: deprecated
----
-* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead.
\ No newline at end of file
diff --git a/cpp/ql/lib/change-notes/released/0.9.2.md b/cpp/ql/lib/change-notes/released/0.9.2.md
new file mode 100644
index 00000000000..93b36c8e40a
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/0.9.2.md
@@ -0,0 +1,14 @@
+## 0.9.2
+
+### Deprecated APIs
+
+* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead.
+
+### New Features
+
+* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr`
+
+### Minor Analysis Improvements
+
+* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation.
+* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml
index 6789dcd18b7..e1eda519435 100644
--- a/cpp/ql/lib/codeql-pack.release.yml
+++ b/cpp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.9.1
+lastReleaseVersion: 0.9.2
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index 1a8ab0be7bb..6c56393b656 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-all
-version: 0.9.2-dev
+version: 0.9.2
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
index e154491f795..229031e0149 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
@@ -3,297 +3,25 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import cpp
+private import DataFlowImplSpecific
+private import TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
-
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
+private module Input implements InputSig {
+ predicate argHasPostUpdateExclude(Private::ArgumentNode n) {
+ // Is the null pointer (or something that's not really a pointer)
+ exists(n.asExpr().getValue())
or
- none()
- }
-
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
- }
-
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
+ // Isn't a pointer or is a pointer to const
+ forall(DerivedType dt | dt = n.asExpr().getActualType() |
+ dt.getBaseType().isConst()
+ or
+ dt.getBaseType() instanceof RoutineType
)
- }
-
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
- }
-
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
+ // The above list of cases isn't exhaustive, but it narrows down the
+ // consistency alerts enough that most of them are interesting.
}
}
+
+module Consistency = MakeConsistency;
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 a6f00f30b27..00eca92b3e4 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -2,7 +2,6 @@ private import cpp
private import DataFlowUtil
private import DataFlowDispatch
private import FlowVar
-private import DataFlowImplConsistency
private import codeql.util.Unit
/** Gets the callable in which this node occurs. */
@@ -297,22 +296,6 @@ class ContentApprox = Unit;
pragma[inline]
ContentApprox getContentApprox(Content c) { any() }
-private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
- // Is the null pointer (or something that's not really a pointer)
- exists(n.asExpr().getValue())
- or
- // Isn't a pointer or is a pointer to const
- forall(DerivedType dt | dt = n.asExpr().getActualType() |
- dt.getBaseType().isConst()
- or
- dt.getBaseType() instanceof RoutineType
- )
- // The above list of cases isn't exhaustive, but it narrows down the
- // consistency alerts enough that most of them are interesting.
- }
-}
-
/**
* Gets an additional term that is added to the `join` and `branch` computations to reflect
* an additional forward or backwards branching factor that is not taken into account
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
index e154491f795..c32f63a619d 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
@@ -3,297 +3,17 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import cpp
+private import DataFlowImplSpecific
+private import TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
-
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
- or
- none()
- }
-
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
- }
-
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
- )
- }
-
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
- }
-
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
+private module Input implements InputSig {
+ predicate argHasPostUpdateExclude(Private::ArgumentNode n) {
+ // The rules for whether an IR argument gets a post-update node are too
+ // complex to model here.
+ any()
}
}
+
+module Consistency = MakeConsistency;
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 329164e0fd0..7e4b87e3853 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
@@ -2,7 +2,6 @@ private import cpp as Cpp
private import DataFlowUtil
private import semmle.code.cpp.ir.IR
private import DataFlowDispatch
-private import DataFlowImplConsistency
private import semmle.code.cpp.ir.internal.IRCppLanguage
private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
@@ -220,9 +219,10 @@ private module IndirectOperands {
int indirectionIndex;
IndirectOperandFromIRRepr() {
- exists(Operand repr |
- repr = Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) and
- nodeHasOperand(this, repr, indirectionIndex - 1)
+ exists(Operand repr, int indirectionIndexRepr |
+ Ssa::hasIRRepresentationOfIndirectOperand(operand, indirectionIndex, repr,
+ indirectionIndexRepr) and
+ nodeHasOperand(this, repr, indirectionIndexRepr)
)
}
@@ -262,9 +262,10 @@ private module IndirectInstructions {
int indirectionIndex;
IndirectInstructionFromIRRepr() {
- exists(Instruction repr |
- repr = Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) and
- nodeHasInstruction(this, repr, indirectionIndex - 1)
+ exists(Instruction repr, int indirectionIndexRepr |
+ Ssa::hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, repr,
+ indirectionIndexRepr) and
+ nodeHasInstruction(this, repr, indirectionIndexRepr)
)
}
@@ -690,7 +691,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { storeStepImpl(node1,
private predicate numberOfLoadsFromOperandRec(
Operand operandFrom, Operand operandTo, int ind, boolean certain
) {
- exists(Instruction load | Ssa::isDereference(load, operandFrom) |
+ exists(Instruction load | Ssa::isDereference(load, operandFrom, _) |
operandTo = operandFrom and ind = 0 and certain = true
or
numberOfLoadsFromOperand(load.getAUse(), operandTo, ind - 1, certain)
@@ -714,7 +715,7 @@ private predicate numberOfLoadsFromOperand(
) {
numberOfLoadsFromOperandRec(operandFrom, operandTo, n, certain)
or
- not Ssa::isDereference(_, operandFrom) and
+ not Ssa::isDereference(_, operandFrom, _) and
not conversionFlow(operandFrom, _, _, _) and
operandFrom = operandTo and
n = 0 and
@@ -1011,14 +1012,6 @@ ContentApprox getContentApprox(Content c) {
)
}
-private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
- // The rules for whether an IR argument gets a post-update node are too
- // complex to model here.
- any()
- }
-}
-
/**
* A local flow relation that includes both local steps, read steps and
* argument-to-return flow through summarized functions.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
index 4e9a90dc0a1..844633ad8d7 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
@@ -74,7 +74,7 @@ predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
type = getLanguageType(op) and
m = countIndirectionsForCppType(type) and
indirectionIndex = [1 .. m] and
- not exists(getIRRepresentationOfIndirectOperand(op, indirectionIndex))
+ not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
)
}
@@ -88,7 +88,7 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
type = getResultLanguageType(instr) and
m = countIndirectionsForCppType(type) and
indirectionIndex = [1 .. m] and
- not exists(getIRRepresentationOfIndirectInstruction(instr, indirectionIndex))
+ not hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, _, _)
)
}
@@ -108,7 +108,7 @@ private newtype TDefOrUseImpl =
} or
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
isUse(_, operand, base, _, indirectionIndex) and
- not isDef(_, _, operand, _, _, _)
+ not isDef(true, _, operand, _, _, _)
} or
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents a final "use" of a global variable to ensure that
@@ -610,7 +610,7 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
hasOperandAndIndex(nTo, op2, indirectionIndex - 1) and
instr = op2.getDef() and
- isDereference(instr, op1)
+ isDereference(instr, op1, _)
)
)
}
@@ -638,12 +638,24 @@ private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) {
)
}
+/**
+ * Holds if `nodeFrom` flows to `nodeTo` because there is `def-use` or
+ * `use-use` flow from `defOrUse` to `use`.
+ *
+ * `uncertain` is `true` if the `defOrUse` is an uncertain definition.
+ */
+private predicate localSsaFlow(
+ SsaDefOrUse defOrUse, Node nodeFrom, UseOrPhi use, Node nodeTo, boolean uncertain
+) {
+ nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
+ adjacentDefRead(defOrUse, use) and
+ useToNode(use, nodeTo) and
+ nodeFrom != nodeTo
+}
+
private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) {
exists(UseOrPhi use |
- nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
- adjacentDefRead(defOrUse, use) and
- useToNode(use, nodeTo) and
- nodeFrom != nodeTo
+ localSsaFlow(defOrUse, nodeFrom, use, nodeTo, uncertain)
or
// Initial global variable value to a first use
nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and
@@ -684,19 +696,99 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) {
)
}
-private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) {
- arg.argumentOf(call, _)
+private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction instr) {
+ isArgumentOfCallableOperand(call, unique( | | getAUse(instr)))
}
-/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */
-predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
- exists(UseOrPhi use, Node preUpdate |
+private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) {
+ operand.(ArgumentOperand).getCall() = call
+ or
+ exists(FieldAddressInstruction fai |
+ fai.getObjectAddressOperand() = operand and
+ isArgumentOfCallableInstruction(call, fai)
+ )
+ or
+ exists(Instruction deref |
+ isArgumentOfCallableInstruction(call, deref) and
+ isDereference(deref, operand, _)
+ )
+ or
+ exists(Instruction instr |
+ isArgumentOfCallableInstruction(call, instr) and
+ conversionFlow(operand, instr, _, _)
+ )
+}
+
+private predicate isArgumentOfCallable(DataFlowCall call, Node n) {
+ isArgumentOfCallableOperand(call, n.asOperand())
+ or
+ exists(Operand op |
+ n.(IndirectOperand).hasOperandAndIndirectionIndex(op, _) and
+ isArgumentOfCallableOperand(call, op)
+ )
+ or
+ exists(Instruction instr |
+ n.(IndirectInstruction).hasInstructionAndIndirectionIndex(instr, _) and
+ isArgumentOfCallableInstruction(call, instr)
+ )
+}
+
+/**
+ * Holds if there is use-use flow from `pun`'s pre-update node to `n`.
+ */
+private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) {
+ exists(UseOrPhi use |
adjustForPointerArith(pun, use) and
- useToNode(use, nodeTo) and
+ useToNode(use, n)
+ )
+}
+
+private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) {
+ isArgumentOfCallable(call, n1) and
+ exists(Node mid | localSsaFlow(_, n1, _, mid, _) |
+ isArgumentOfCallable(call, mid) and
+ stepUntilNotInCall(call, mid, n2)
+ or
+ not isArgumentOfCallable(call, mid) and
+ mid = n2
+ )
+}
+
+bindingset[n1, n2]
+pragma[inline_late]
+private predicate isArgumentOfSameCall(DataFlowCall call, Node n1, Node n2) {
+ isArgumentOfCallable(call, n1) and isArgumentOfCallable(call, n2)
+}
+
+/**
+ * Holds if there is def-use or use-use flow from `pun` to `nodeTo`.
+ *
+ * Note: This is more complex than it sounds. Consider a call such as:
+ * ```cpp
+ * write_first_argument(x, x);
+ * sink(x);
+ * ```
+ * Assume flow comes out of the first argument to `write_first_argument`. We
+ * don't want flow to go to the `x` that's also an argument to
+ * `write_first_argument` (because we just flowed out of that function, and we
+ * don't want to flow back into it again).
+ *
+ * We do, however, want flow from the output argument to `x` on the next line, and
+ * similarly we want flow from the second argument of `write_first_argument` to `x`
+ * on the next line.
+ */
+predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
+ exists(Node preUpdate, Node mid |
preUpdate = pun.getPreUpdateNode() and
- not exists(DataFlowCall call |
- isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo)
+ postUpdateNodeToFirstUse(pun, mid)
+ |
+ exists(DataFlowCall call |
+ isArgumentOfSameCall(call, preUpdate, mid) and
+ stepUntilNotInCall(call, mid, nodeTo)
)
+ or
+ not isArgumentOfSameCall(_, preUpdate, mid) and
+ nodeTo = mid
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
index 4410e2e9e69..27948d68913 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
@@ -320,10 +320,20 @@ private module IteratorIndirections {
}
}
-predicate isDereference(Instruction deref, Operand address) {
- any(Indirection ind).isAdditionalDereference(deref, address)
+/**
+ * Holds if `deref` is the result of loading the value at the address
+ * represented by `address`.
+ *
+ * If `additional = true` then the dereference comes from an `Indirection`
+ * class (such as a call to an iterator's `operator*`), and if
+ * `additional = false` the dereference is a `LoadInstruction`.
+ */
+predicate isDereference(Instruction deref, Operand address, boolean additional) {
+ any(Indirection ind).isAdditionalDereference(deref, address) and
+ additional = true
or
- deref.(LoadInstruction).getSourceAddressOperand() = address
+ deref.(LoadInstruction).getSourceAddressOperand() = address and
+ additional = false
}
predicate isWrite(Node0Impl value, Operand address, boolean certain) {
@@ -545,7 +555,7 @@ private module Cached {
isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and
isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and
iteratorBase.getResultType() instanceof Interfaces::Iterator and
- isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse()) and
+ isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and
memory = read.getSideEffectOperand().getAnyDef()
)
}
@@ -781,11 +791,14 @@ private module Cached {
* instead associated with the operand returned by this predicate.
*/
cached
- Operand getIRRepresentationOfIndirectOperand(Operand operand, int indirectionIndex) {
+ predicate hasIRRepresentationOfIndirectOperand(
+ Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr
+ ) {
+ indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and
exists(Instruction load |
- isDereference(load, operand) and
- result = unique( | | getAUse(load)) and
- isUseImpl(operand, _, indirectionIndex - 1)
+ isDereference(load, operand, false) and
+ operandRepr = unique( | | getAUse(load)) and
+ indirectionIndexRepr = indirectionIndex - 1
)
}
@@ -797,12 +810,15 @@ private module Cached {
* instead associated with the instruction returned by this predicate.
*/
cached
- Instruction getIRRepresentationOfIndirectInstruction(Instruction instr, int indirectionIndex) {
+ predicate hasIRRepresentationOfIndirectInstruction(
+ Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr
+ ) {
+ indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
exists(Instruction load, Operand address |
address.getDef() = instr and
- isDereference(load, address) and
- isUseImpl(address, _, indirectionIndex - 1) and
- result = load
+ isDereference(load, address, false) and
+ instrRepr = load and
+ indirectionIndexRepr = indirectionIndex - 1
)
}
@@ -823,7 +839,7 @@ private module Cached {
or
exists(int ind0 |
exists(Operand address |
- isDereference(operand.getDef(), address) and
+ isDereference(operand.getDef(), address, _) and
isUseImpl(address, base, ind0)
)
or
@@ -893,7 +909,7 @@ private module Cached {
)
or
exists(Operand address, boolean certain0 |
- isDereference(operand.getDef(), address) and
+ isDereference(operand.getDef(), address, _) and
isDefImpl(address, base, ind - 1, certain0)
|
if isCertainAddress(operand) then certain = certain0 else certain = false
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
index 50e45e3081d..fd4169edd7d 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
@@ -57,7 +57,7 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst
)
or
// Taint flow from an address to its dereference.
- Ssa::isDereference(instrTo, opFrom)
+ Ssa::isDereference(instrTo, opFrom, _)
or
// Unary instructions tend to preserve enough information in practice that we
// want taint to flow through.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll
index a9ecdf46984..c473969467d 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll
@@ -55,6 +55,7 @@ private newtype TOpcode =
TVariableAddress() or
TFieldAddress() or
TFunctionAddress() or
+ TVirtualDeleteFunctionAddress() or
TElementsAddress() or
TConstant() or
TStringConstant() or
@@ -887,6 +888,15 @@ module Opcode {
final override string toString() { result = "FunctionAddress" }
}
+ /**
+ * The `Opcode` for a `VirtualDeleteFunctionAddress`.
+ *
+ * See the `VirtualDeleteFunctionAddressInstruction` documentation for more details.
+ */
+ class VirtualDeleteFunctionAddress extends Opcode, TVirtualDeleteFunctionAddress {
+ final override string toString() { result = "VirtualDeleteFunctionAddress" }
+ }
+
/**
* The `Opcode` for a `ConstantInstruction`.
*
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
index 1b5ea432946..2a3a6d3407a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
+/**
+ * An instruction that returns the address of a "virtual" delete function.
+ *
+ * This function, which does not actually exist in the source code, is used to
+ * delete objects of a class with a virtual destructor. In that case the deacllocation
+ * function is selected at runtime based on the dynamic type of the object. So this
+ * function dynamically dispatches to the correct deallocation function.
+ * It also should pass in the required extra arguments to the deallocation function
+ * which may differ dynamically depending on the type of the object.
+ */
+class VirtualDeleteFunctionAddressInstruction extends Instruction {
+ VirtualDeleteFunctionAddressInstruction() {
+ this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+}
+
/**
* An instruction that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
index 1b5ea432946..2a3a6d3407a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
+/**
+ * An instruction that returns the address of a "virtual" delete function.
+ *
+ * This function, which does not actually exist in the source code, is used to
+ * delete objects of a class with a virtual destructor. In that case the deacllocation
+ * function is selected at runtime based on the dynamic type of the object. So this
+ * function dynamically dispatches to the correct deallocation function.
+ * It also should pass in the required extra arguments to the deallocation function
+ * which may differ dynamically depending on the type of the object.
+ */
+class VirtualDeleteFunctionAddressInstruction extends Instruction {
+ VirtualDeleteFunctionAddressInstruction() {
+ this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+}
+
/**
* An instruction that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
index 684aa4f14f2..187cde6e700 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
@@ -120,9 +120,9 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
}
/**
- * A `Call` or `NewOrNewArrayExpr`.
+ * A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`.
*
- * Both kinds of expression invoke a function as part of their evaluation. This class provides a
+ * All kinds of expression invoke a function as part of their evaluation. This class provides a
* way to treat both kinds of function similarly, and to get the invoked `Function`.
*/
class CallOrAllocationExpr extends Expr {
@@ -130,6 +130,8 @@ class CallOrAllocationExpr extends Expr {
this instanceof Call
or
this instanceof NewOrNewArrayExpr
+ or
+ this instanceof DeleteOrDeleteArrayExpr
}
/** Gets the `Function` invoked by this expression, if known. */
@@ -137,6 +139,8 @@ class CallOrAllocationExpr extends Expr {
result = this.(Call).getTarget()
or
result = this.(NewOrNewArrayExpr).getAllocator()
+ or
+ result = this.(DeleteOrDeleteArrayExpr).getDeallocator()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
index 68f7a5fbdb4..7079354f098 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
@@ -350,6 +350,9 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
or
expr instanceof NewOrNewArrayExpr and
result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
+ or
+ expr instanceof DeleteOrDeleteArrayExpr and
+ result = getTranslatedDeleteOrDeleteArray(expr).getInstruction(CallTag())
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
index 0efc7e7af3a..409d76f4fd5 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
@@ -77,17 +77,17 @@ private predicate ignoreExprAndDescendants(Expr expr) {
newExpr.getInitializer().getFullyConverted() = expr
)
or
+ exists(DeleteOrDeleteArrayExpr deleteExpr |
+ // Ignore the deallocator call, because we always synthesize it.
+ deleteExpr.getDeallocatorCall() = expr
+ )
+ or
// Do not translate input/output variables in GNU asm statements
// getRealParent(expr) instanceof AsmStmt
// or
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
or
- // We do not yet translate destructors properly, so for now we ignore any
- // custom deallocator call, if present.
- exists(DeleteExpr deleteExpr | deleteExpr.getDeallocatorCall() = expr)
- or
- exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDeallocatorCall() = expr)
- or
+ // va_start doesn't evaluate its argument, so we don't need to translate it.
exists(BuiltInVarArgsStart vaStartExpr |
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
)
@@ -104,6 +104,12 @@ private predicate ignoreExprOnly(Expr expr) {
newExpr.getAllocatorCall() = expr
)
or
+ exists(DeleteOrDeleteArrayExpr deleteExpr |
+ // Ignore the destructor call as we don't model it yet. Don't ignore
+ // its arguments, though, as they are the arguments to the deallocator.
+ deleteExpr.getDestructorCall() = expr
+ )
+ or
// The extractor deliberately emits an `ErrorExpr` as the first argument to
// the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr`
// should not be translated.
@@ -111,13 +117,6 @@ private predicate ignoreExprOnly(Expr expr) {
or
not translateFunction(getEnclosingFunction(expr)) and
not Raw::varHasIRFunc(getEnclosingVariable(expr))
- or
- // We do not yet translate destructors properly, so for now we ignore the
- // destructor call. We do, however, translate the expression being
- // destructed, and that expression can be a child of the destructor call.
- exists(DeleteExpr deleteExpr | deleteExpr.getDestructorCall() = expr)
- or
- exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDestructorCall() = expr)
}
/**
@@ -416,7 +415,9 @@ predicate hasTranslatedLoad(Expr expr) {
not ignoreExpr(expr) and
not isNativeCondition(expr) and
not isFlexibleCondition(expr) and
- not ignoreLoad(expr)
+ not ignoreLoad(expr) and
+ // don't insert a load since we'll just substitute the constant value.
+ not isIRConstant(expr)
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
index 4f93f5d3702..5589786ce39 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -2017,6 +2017,66 @@ TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
result.getAst() = newExpr
}
+/**
+ * The IR translation of a `delete` or `delete[]`
+ * expression.
+ */
+class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, TranslatedCall {
+ override DeleteOrDeleteArrayExpr expr;
+
+ final override Instruction getFirstCallTargetInstruction() {
+ result = this.getInstruction(CallTargetTag())
+ }
+
+ final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
+ TranslatedCall.super.hasInstruction(opcode, tag, resultType)
+ or
+ tag = CallTargetTag() and
+ resultType = getFunctionGLValueType() and
+ if exists(expr.getDeallocator())
+ then opcode instanceof Opcode::FunctionAddress
+ else opcode instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+
+ override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
+ result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
+ or
+ tag = CallTargetTag() and
+ kind instanceof GotoEdge and
+ result = this.getFirstArgumentOrCallInstruction()
+ }
+
+ override Function getInstructionFunction(InstructionTag tag) {
+ tag = CallTargetTag() and result = expr.getDeallocator()
+ }
+
+ final override Type getCallResultType() { result = expr.getType() }
+
+ final override TranslatedExpr getQualifier() { none() }
+
+ final override predicate hasArguments() {
+ // All deallocator calls have at least one argument.
+ any()
+ }
+
+ final override int getNumberOfArguments() {
+ // We ignore the other arguments for now as we would have to synthesize them.
+ result = 1
+ }
+
+ final override TranslatedExpr getArgument(int index) {
+ // The only argument we define is the pointer to be deallocated.
+ index = 0 and
+ result = getTranslatedExpr(expr.getExpr().getFullyConverted())
+ }
+}
+
+TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) {
+ result.getAst() = newExpr
+}
+
/**
* Abstract class implemented by any `TranslatedElement` that has a child
* expression that is a call to a constructor or destructor, in order to
@@ -2954,78 +3014,6 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
}
}
-/**
- * A placeholder for the translation of a `delete[]` expression.
- *
- * Proper translation is not yet implemented, but this stub implementation
- * ensures that code following a `delete[]` is not unreachable.
- */
-class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionExpr {
- override DeleteArrayExpr expr;
-
- final override Instruction getFirstInstruction() {
- result = this.getOperand().getFirstInstruction()
- }
-
- final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
-
- final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
- tag = OnlyInstructionTag() and
- result = this.getParent().getChildSuccessor(this) and
- kind instanceof GotoEdge
- }
-
- final override Instruction getChildSuccessor(TranslatedElement child) {
- child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
- }
-
- final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
- none()
- }
-
- final override Opcode getOpcode() { result instanceof Opcode::NoOp }
-
- private TranslatedExpr getOperand() {
- result = getTranslatedExpr(expr.getExpr().getFullyConverted())
- }
-}
-
-/**
- * A placeholder for the translation of a `delete` expression.
- *
- * Proper translation is not yet implemented, but this stub implementation
- * ensures that code following a `delete` is not unreachable.
- */
-class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr {
- override DeleteExpr expr;
-
- final override Instruction getFirstInstruction() {
- result = this.getOperand().getFirstInstruction()
- }
-
- final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
-
- final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
- tag = OnlyInstructionTag() and
- result = this.getParent().getChildSuccessor(this) and
- kind instanceof GotoEdge
- }
-
- final override Instruction getChildSuccessor(TranslatedElement child) {
- child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
- }
-
- final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
- none()
- }
-
- final override Opcode getOpcode() { result instanceof Opcode::NoOp }
-
- private TranslatedExpr getOperand() {
- result = getTranslatedExpr(expr.getExpr().getFullyConverted())
- }
-}
-
/**
* The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable
* after conversion to `bool` in code such as:
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
index 1b5ea432946..2a3a6d3407a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
+/**
+ * An instruction that returns the address of a "virtual" delete function.
+ *
+ * This function, which does not actually exist in the source code, is used to
+ * delete objects of a class with a virtual destructor. In that case the deacllocation
+ * function is selected at runtime based on the dynamic type of the object. So this
+ * function dynamically dispatches to the correct deallocation function.
+ * It also should pass in the required extra arguments to the deallocation function
+ * which may differ dynamically depending on the type of the object.
+ */
+class VirtualDeleteFunctionAddressInstruction extends Instruction {
+ VirtualDeleteFunctionAddressInstruction() {
+ this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+}
+
/**
* An instruction that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md
index f3d5cd46f66..6edc055a334 100644
--- a/cpp/ql/src/CHANGELOG.md
+++ b/cpp/ql/src/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 0.7.4
+
+### New Queries
+
+* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
+
+### Minor Analysis Improvements
+
+* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions.
+* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
+* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
+
## 0.7.3
No user-facing changes.
diff --git a/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md b/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md
deleted file mode 100644
index d8207a75604..00000000000
--- a/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: newQuery
----
-* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
diff --git a/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md b/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md
deleted file mode 100644
index 74b8e6910da..00000000000
--- a/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
diff --git a/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md b/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md
deleted file mode 100644
index f4dcc011a29..00000000000
--- a/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
diff --git a/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md b/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md
deleted file mode 100644
index 8872ba413fb..00000000000
--- a/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions.
diff --git a/cpp/ql/src/change-notes/released/0.7.4.md b/cpp/ql/src/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..bdec41d4f69
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/0.7.4.md
@@ -0,0 +1,11 @@
+## 0.7.4
+
+### New Queries
+
+* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
+
+### Minor Analysis Improvements
+
+* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions.
+* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
+* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/cpp/ql/src/codeql-pack.release.yml
+++ b/cpp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml
index fd076044593..0fe920a9439 100644
--- a/cpp/ql/src/qlpack.yml
+++ b/cpp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-queries
-version: 0.7.4-dev
+version: 0.7.4
groups:
- cpp
- queries
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected
index dbd71611d81..15a601b27f0 100644
--- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected
@@ -9,44 +9,35 @@ edges
| test.cpp:22:5:22:7 | arr indirection [p] | test.cpp:19:9:19:16 | mk_array indirection [p] |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | arr indirection [p] |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | arr indirection [p] |
-| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p indirection |
-| test.cpp:31:13:31:13 | p indirection | test.cpp:31:13:31:13 | p |
-| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p indirection |
-| test.cpp:35:13:35:13 | p indirection | test.cpp:35:13:35:13 | p |
+| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p |
+| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | arr indirection [p] |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | arr indirection [p] |
-| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p indirection |
-| test.cpp:41:13:41:13 | p indirection | test.cpp:41:13:41:13 | p |
-| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p indirection |
-| test.cpp:45:13:45:13 | p indirection | test.cpp:45:13:45:13 | p |
+| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p |
+| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p |
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] |
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:9:55:9 | arr indirection [post update] [p] |
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | test.cpp:56:5:56:7 | arr indirection [p] |
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... |
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:59:9:59:11 | arr indirection [p] |
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:63:9:63:11 | arr indirection [p] |
-| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p indirection |
-| test.cpp:59:13:59:13 | p indirection | test.cpp:59:13:59:13 | p |
-| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p indirection |
-| test.cpp:63:13:63:13 | p indirection | test.cpp:63:13:63:13 | p |
+| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p |
+| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p |
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] |
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] |
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:10:69:10 | arr indirection [post update] [p] |
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
+| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] |
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
-| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p indirection |
-| test.cpp:79:14:79:14 | p indirection | test.cpp:79:14:79:14 | p |
-| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p indirection |
-| test.cpp:83:14:83:14 | p indirection | test.cpp:83:14:83:14 | p |
+| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |
+| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p |
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:89:9:89:11 | arr indirection [p] |
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:93:9:93:11 | arr indirection [p] |
-| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p indirection |
-| test.cpp:89:14:89:14 | p indirection | test.cpp:89:14:89:14 | p |
-| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p indirection |
-| test.cpp:93:14:93:14 | p indirection | test.cpp:93:14:93:14 | p |
+| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p |
+| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p |
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | test.cpp:87:28:87:30 | arr indirection [p] |
nodes
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
@@ -60,17 +51,13 @@ nodes
| test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] |
| test.cpp:31:9:31:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:31:13:31:13 | p | semmle.label | p |
-| test.cpp:31:13:31:13 | p indirection | semmle.label | p indirection |
| test.cpp:35:9:35:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:35:13:35:13 | p | semmle.label | p |
-| test.cpp:35:13:35:13 | p indirection | semmle.label | p indirection |
| test.cpp:39:27:39:29 | arr [p] | semmle.label | arr [p] |
| test.cpp:41:9:41:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:41:13:41:13 | p | semmle.label | p |
-| test.cpp:41:13:41:13 | p indirection | semmle.label | p indirection |
| test.cpp:45:9:45:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:45:13:45:13 | p | semmle.label | p |
-| test.cpp:45:13:45:13 | p indirection | semmle.label | p indirection |
| test.cpp:50:18:50:25 | call to mk_array [p] | semmle.label | call to mk_array [p] |
| test.cpp:55:5:55:24 | ... = ... | semmle.label | ... = ... |
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
@@ -78,10 +65,8 @@ nodes
| test.cpp:56:5:56:7 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:59:9:59:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:59:13:59:13 | p | semmle.label | p |
-| test.cpp:59:13:59:13 | p indirection | semmle.label | p indirection |
| test.cpp:63:9:63:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:63:13:63:13 | p | semmle.label | p |
-| test.cpp:63:13:63:13 | p indirection | semmle.label | p indirection |
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | semmle.label | mk_array_p indirection [p] |
| test.cpp:69:5:69:25 | ... = ... | semmle.label | ... = ... |
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
@@ -90,17 +75,13 @@ nodes
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
| test.cpp:79:9:79:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:79:14:79:14 | p | semmle.label | p |
-| test.cpp:79:14:79:14 | p indirection | semmle.label | p indirection |
| test.cpp:83:9:83:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:83:14:83:14 | p | semmle.label | p |
-| test.cpp:83:14:83:14 | p indirection | semmle.label | p indirection |
| test.cpp:87:28:87:30 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:89:9:89:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:89:14:89:14 | p | semmle.label | p |
-| test.cpp:89:14:89:14 | p indirection | semmle.label | p indirection |
| test.cpp:93:9:93:11 | arr indirection [p] | semmle.label | arr indirection [p] |
| test.cpp:93:14:93:14 | p | semmle.label | p |
-| test.cpp:93:14:93:14 | p indirection | semmle.label | p indirection |
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
subpaths
#select
diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected
index 4cac8898022..fe5eed1b916 100644
--- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected
+++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected
@@ -1,4 +1,4 @@
WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:10,8-47)
WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:21,3-28)
-failures
testFailures
+failures
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp
new file mode 100644
index 00000000000..f3d135cce60
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp
@@ -0,0 +1,14 @@
+namespace {
+ struct Foo {
+ char string[10];
+ };
+
+ void acquire(char*);
+
+ Foo* test_self_argument_flow() {
+ Foo *info;
+ acquire(info->string); // clean
+
+ return info;
+ }
+}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
index c49d9092cd7..c5f7ffcf160 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
@@ -788,4 +788,12 @@ void test_sometimes_calls_sink_switch() {
sometimes_calls_sink_switch(source(), 1);
sometimes_calls_sink_switch(0, 0);
sometimes_calls_sink_switch(source(), 0);
+}
+
+void intPointerSource(int *ref_source, const int* another_arg);
+
+void test() {
+ MyStruct a;
+ intPointerSource(a.content, a.content);
+ indirect_sink(a.content); // $ ast ir
}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
index 0260ed62b05..d4756e8d808 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected
@@ -5,5 +5,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (test.
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:40,25-33)
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:42,17-25)
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:46,20-28)
-failures
testFailures
+failures
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected
new file mode 100644
index 00000000000..8ec8033d086
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected
@@ -0,0 +1,2 @@
+testFailures
+failures
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql
new file mode 100644
index 00000000000..95f992f39f5
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql
@@ -0,0 +1,33 @@
+import cpp
+import semmle.code.cpp.dataflow.new.DataFlow
+import TestUtilities.InlineExpectationsTest
+
+module TestConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) {
+ source.getLocation().getFile().getBaseName() = "self_argument_flow.cpp" and
+ source.asDefiningArgument() =
+ any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
+ }
+
+ predicate isSink(DataFlow::Node sink) {
+ sink.asIndirectArgument() = any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
+ }
+}
+
+import DataFlow::Global
+
+module TestSelfArgumentFlow implements TestSig {
+ string getARelevantTag() { result = "self-arg-flow" }
+
+ predicate hasActualResult(Location location, string element, string tag, string value) {
+ exists(DataFlow::Node sink |
+ flowTo(sink) and
+ location = sink.getLocation() and
+ element = sink.toString() and
+ tag = "self-arg-flow" and
+ value = ""
+ )
+ }
+}
+
+import MakeTest
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected
index b40148f4950..72290967857 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected
@@ -14,6 +14,8 @@
| ref.cpp:120:17:120:18 | x3 | ref.cpp:129:10:129:11 | x3 |
| ref.cpp:120:21:120:22 | x4 | ref.cpp:131:15:131:16 | x4 |
| ref.cpp:120:21:120:22 | x4 | ref.cpp:132:10:132:11 | x4 |
+| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:10:13:10:16 | info |
+| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:12:12:12:15 | info |
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
| test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 |
| test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 |
@@ -44,3 +46,6 @@
| test.cpp:595:8:595:9 | xs | test.cpp:597:9:597:10 | xs |
| test.cpp:733:7:733:7 | x | test.cpp:734:41:734:41 | x |
| test.cpp:733:7:733:7 | x | test.cpp:735:8:735:8 | x |
+| test.cpp:796:12:796:12 | a | test.cpp:797:20:797:20 | a |
+| test.cpp:796:12:796:12 | a | test.cpp:797:31:797:31 | a |
+| test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a |
diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.expected b/cpp/ql/test/library-tests/dataflow/fields/flow.expected
index 48de9172b36..8ec8033d086 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/flow.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/flow.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
index 6dce17b97bf..bde0ebd2586 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
@@ -5,9 +5,7 @@ edges
| A.cpp:27:22:27:32 | ... = ... | A.cpp:27:28:27:28 | this indirection [post update] [c] |
| A.cpp:28:8:28:10 | this indirection [c] | A.cpp:28:23:28:26 | this indirection [c] |
| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c |
-| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c indirection |
| A.cpp:28:29:28:29 | c | A.cpp:28:8:28:10 | get indirection |
-| A.cpp:28:29:28:29 | c indirection | A.cpp:28:8:28:10 | get indirection |
| A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c |
| A.cpp:31:14:31:21 | call to B [c] | A.cpp:29:15:29:18 | make indirection [c] |
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c |
@@ -21,9 +19,7 @@ edges
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make indirection [c] |
| A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:10:49:13 | c |
-| A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:13:49:13 | c indirection |
-| A.cpp:49:13:49:13 | c indirection | A.cpp:49:10:49:13 | c |
-| A.cpp:49:13:49:13 | c indirection | A.cpp:49:13:49:13 | c |
+| A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:13:49:13 | c |
| A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | b indirection [c] |
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c |
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | set output argument [c] |
@@ -41,17 +37,13 @@ edges
| A.cpp:64:21:64:28 | new | A.cpp:64:21:64:28 | new |
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c |
| A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:10:66:14 | c |
-| A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:14:66:14 | c indirection |
-| A.cpp:66:14:66:14 | c indirection | A.cpp:66:10:66:14 | c |
-| A.cpp:66:14:66:14 | c indirection | A.cpp:66:14:66:14 | c |
+| A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:14:66:14 | c |
| A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] | A.cpp:75:10:75:11 | b2 indirection [c] |
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] |
| A.cpp:73:25:73:32 | new | A.cpp:73:25:73:32 | new |
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c |
| A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:10:75:14 | c |
-| A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:14:75:14 | c indirection |
-| A.cpp:75:14:75:14 | c indirection | A.cpp:75:10:75:14 | c |
-| A.cpp:75:14:75:14 | c indirection | A.cpp:75:14:75:14 | c |
+| A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:14:75:14 | c |
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c |
| A.cpp:81:10:81:15 | call to setOnB indirection [c] | A.cpp:78:6:78:15 | setOnBWrap indirection [c] |
| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB indirection [c] |
@@ -67,22 +59,16 @@ edges
| A.cpp:103:14:103:14 | c indirection [a] | A.cpp:107:12:107:13 | c1 indirection [a] |
| A.cpp:103:14:103:14 | c indirection [a] | A.cpp:120:12:120:13 | c1 indirection [a] |
| A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:12:107:16 | a |
-| A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:16:107:16 | a indirection |
-| A.cpp:107:16:107:16 | a indirection | A.cpp:107:12:107:16 | a |
-| A.cpp:107:16:107:16 | a indirection | A.cpp:107:16:107:16 | a |
+| A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:16:107:16 | a |
| A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:12:120:16 | a |
-| A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:16:120:16 | a indirection |
-| A.cpp:120:16:120:16 | a indirection | A.cpp:120:12:120:16 | a |
-| A.cpp:120:16:120:16 | a indirection | A.cpp:120:16:120:16 | a |
+| A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:16:120:16 | a |
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:131:8:131:8 | f7 output argument [c] |
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c |
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | set output argument [c] |
| A.cpp:126:12:126:18 | new | A.cpp:126:12:126:18 | new |
| A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:132:10:132:10 | b indirection [c] |
| A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:10:132:13 | c |
-| A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:13:132:13 | c indirection |
-| A.cpp:132:13:132:13 | c indirection | A.cpp:132:10:132:13 | c |
-| A.cpp:132:13:132:13 | c indirection | A.cpp:132:13:132:13 | c |
+| A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:13:132:13 | c |
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... |
| A.cpp:142:7:142:20 | ... = ... | A.cpp:142:10:142:10 | b indirection [post update] [c] |
| A.cpp:142:10:142:10 | b indirection [post update] [c] | A.cpp:143:7:143:31 | ... = ... indirection [c] |
@@ -101,20 +87,13 @@ edges
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b |
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:10:152:13 | b |
-| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:13:152:13 | b indirection |
-| A.cpp:152:13:152:13 | b indirection | A.cpp:152:10:152:13 | b |
-| A.cpp:152:13:152:13 | b indirection | A.cpp:152:13:152:13 | b |
-| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] |
+| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:13:152:13 | b |
| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] |
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:10:153:16 | c |
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:13:153:13 | b indirection [c] |
-| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:16:153:16 | c indirection |
-| A.cpp:153:16:153:16 | c indirection | A.cpp:153:10:153:16 | c |
-| A.cpp:153:16:153:16 | c indirection | A.cpp:153:16:153:16 | c |
+| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:16:153:16 | c |
| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:10:154:13 | c |
-| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:13:154:13 | c indirection |
-| A.cpp:154:13:154:13 | c indirection | A.cpp:154:10:154:13 | c |
-| A.cpp:154:13:154:13 | c indirection | A.cpp:154:13:154:13 | c |
+| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:13:154:13 | c |
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 indirection [head] |
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
@@ -127,27 +106,17 @@ edges
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:162:18:162:40 | call to MyList [next indirection, next indirection, head] |
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:181:32:181:35 | next indirection [next indirection, head] |
| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
-| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] |
-| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] |
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:10:165:29 | head |
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:20:165:23 | next indirection [head] |
-| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:26:165:29 | head indirection |
-| A.cpp:165:26:165:29 | head indirection | A.cpp:165:10:165:29 | head |
-| A.cpp:165:26:165:29 | head indirection | A.cpp:165:26:165:29 | head |
-| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] |
+| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:26:165:29 | head |
| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] |
| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] |
-| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] |
| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] |
-| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] |
-| A.cpp:167:47:167:50 | next indirection [next indirection, head] | A.cpp:167:44:167:44 | l indirection [next indirection, head] |
| A.cpp:167:47:167:50 | next indirection [next indirection, head] | A.cpp:167:44:167:44 | l indirection [next indirection, head] |
| A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:12:169:18 | head |
-| A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:15:169:18 | head indirection |
-| A.cpp:169:15:169:18 | head indirection | A.cpp:169:12:169:18 | head |
-| A.cpp:169:15:169:18 | head indirection | A.cpp:169:15:169:18 | head |
+| A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:15:169:18 | head |
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... |
| A.cpp:181:32:181:35 | next indirection [head] | A.cpp:184:7:184:23 | ... = ... indirection [head] |
| A.cpp:181:32:181:35 | next indirection [next indirection, head] | A.cpp:184:7:184:23 | ... = ... indirection [next indirection, head] |
@@ -162,12 +131,9 @@ edges
| B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:8:16:8:27 | call to Box2 [box1 indirection, elem1] |
| B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:44:16:44:17 | b1 indirection [elem1] |
| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
-| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:10:9:24 | elem1 |
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
-| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:20:9:24 | elem1 indirection |
-| B.cpp:9:20:9:24 | elem1 indirection | B.cpp:9:10:9:24 | elem1 |
-| B.cpp:9:20:9:24 | elem1 indirection | B.cpp:9:20:9:24 | elem1 |
+| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:20:9:24 | elem1 |
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 indirection [elem2] |
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
@@ -176,12 +142,9 @@ edges
| B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:17:16:17:27 | call to Box2 [box1 indirection, elem2] |
| B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:44:16:44:17 | b1 indirection [elem2] |
| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
-| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:10:19:24 | elem2 |
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
-| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:20:19:24 | elem2 indirection |
-| B.cpp:19:20:19:24 | elem2 indirection | B.cpp:19:10:19:24 | elem2 |
-| B.cpp:19:20:19:24 | elem2 indirection | B.cpp:19:20:19:24 | elem2 |
+| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:20:19:24 | elem2 |
| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... |
| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... |
| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:13:35:17 | this indirection [post update] [elem1] |
@@ -202,23 +165,15 @@ edges
| C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | ... = ... |
| C.cpp:27:8:27:11 | this indirection [s1] | C.cpp:29:10:29:11 | this indirection [s1] |
| C.cpp:27:8:27:11 | this indirection [s3] | C.cpp:31:10:31:11 | this indirection [s3] |
-| C.cpp:29:10:29:11 | s1 indirection | C.cpp:29:10:29:11 | s1 |
| C.cpp:29:10:29:11 | this indirection [s1] | C.cpp:29:10:29:11 | s1 |
-| C.cpp:29:10:29:11 | this indirection [s1] | C.cpp:29:10:29:11 | s1 indirection |
-| C.cpp:31:10:31:11 | s3 indirection | C.cpp:31:10:31:11 | s3 |
| C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 |
-| C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 indirection |
| D.cpp:10:11:10:17 | this indirection [elem] | D.cpp:10:30:10:33 | this indirection [elem] |
| D.cpp:10:30:10:33 | elem | D.cpp:10:11:10:17 | getElem indirection |
-| D.cpp:10:30:10:33 | elem indirection | D.cpp:10:11:10:17 | getElem indirection |
| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem |
-| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem indirection |
| D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... |
| D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | this indirection [post update] [elem] |
| D.cpp:17:11:17:17 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | this indirection [box indirection, elem] |
| D.cpp:17:30:17:32 | box indirection [elem] | D.cpp:17:11:17:17 | getBox1 indirection [elem] |
-| D.cpp:17:30:17:32 | box indirection [elem] | D.cpp:17:11:17:17 | getBox1 indirection [elem] |
-| D.cpp:17:30:17:32 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | box indirection [elem] |
| D.cpp:17:30:17:32 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | box indirection [elem] |
| D.cpp:21:30:21:31 | b2 indirection [box indirection, elem] | D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] |
| D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] | D.cpp:17:11:17:17 | this indirection [box indirection, elem] |
@@ -256,20 +211,16 @@ edges
| D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] |
-| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] |
-| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:10:64:28 | elem |
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:20:64:22 | box indirection [elem] |
-| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:25:64:28 | elem indirection |
-| D.cpp:64:25:64:28 | elem indirection | D.cpp:64:10:64:28 | elem |
-| D.cpp:64:25:64:28 | elem indirection | D.cpp:64:25:64:28 | elem |
+| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:25:64:28 | elem |
| E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] |
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | E.cpp:21:13:21:16 | data indirection [buffer indirection] |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
-| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection |
+| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection |
| E.cpp:29:21:29:29 | argument_source output argument | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] |
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | E.cpp:32:10:32:10 | b indirection [buffer indirection] |
@@ -279,6 +230,7 @@ edges
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
+| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] |
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] |
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
@@ -289,25 +241,17 @@ edges
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:29:8:29:9 | s1 indirection [m1] |
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:30:8:30:9 | s2 indirection [m1] |
| aliasing.cpp:29:8:29:9 | s1 indirection [m1] | aliasing.cpp:29:11:29:12 | m1 |
-| aliasing.cpp:29:8:29:9 | s1 indirection [m1] | aliasing.cpp:29:11:29:12 | m1 indirection |
-| aliasing.cpp:29:11:29:12 | m1 indirection | aliasing.cpp:29:11:29:12 | m1 |
| aliasing.cpp:30:8:30:9 | s2 indirection [m1] | aliasing.cpp:30:11:30:12 | m1 |
-| aliasing.cpp:30:8:30:9 | s2 indirection [m1] | aliasing.cpp:30:11:30:12 | m1 indirection |
-| aliasing.cpp:30:11:30:12 | m1 indirection | aliasing.cpp:30:11:30:12 | m1 |
| aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] |
| aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] | aliasing.cpp:62:8:62:12 | copy2 indirection [m1] |
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... |
| aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | aliasing.cpp:62:14:62:15 | m1 |
-| aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | aliasing.cpp:62:14:62:15 | m1 indirection |
-| aliasing.cpp:62:14:62:15 | m1 indirection | aliasing.cpp:62:14:62:15 | m1 |
| aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] |
| aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] | aliasing.cpp:93:8:93:8 | w indirection [s, m1] |
| aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] | aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] |
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
| aliasing.cpp:93:8:93:8 | w indirection [s, m1] | aliasing.cpp:93:10:93:10 | s indirection [m1] |
| aliasing.cpp:93:10:93:10 | s indirection [m1] | aliasing.cpp:93:12:93:13 | m1 |
-| aliasing.cpp:93:10:93:10 | s indirection [m1] | aliasing.cpp:93:12:93:13 | m1 indirection |
-| aliasing.cpp:93:12:93:13 | m1 indirection | aliasing.cpp:93:12:93:13 | m1 |
| aliasing.cpp:98:3:98:21 | ... = ... | aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] |
| aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] | aliasing.cpp:101:14:101:19 | s_copy indirection [m1] |
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:3:98:21 | ... = ... |
@@ -331,41 +275,29 @@ edges
| aliasing.cpp:141:17:141:20 | s indirection [post update] [data indirection] | aliasing.cpp:143:8:143:8 | s indirection [data indirection] |
| aliasing.cpp:141:17:141:20 | taint_a_ptr output argument | aliasing.cpp:141:17:141:20 | s indirection [post update] [data indirection] |
| aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:8:143:16 | access to array |
-| aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:8:143:16 | access to array indirection |
| aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:10:143:13 | data indirection |
-| aliasing.cpp:143:8:143:16 | access to array indirection | aliasing.cpp:143:8:143:16 | access to array |
| aliasing.cpp:143:10:143:13 | data indirection | aliasing.cpp:143:8:143:16 | access to array |
| aliasing.cpp:158:15:158:20 | taint_a_ptr output argument | aliasing.cpp:158:17:158:20 | s indirection [post update] [data] |
| aliasing.cpp:158:17:158:20 | s indirection [post update] [data] | aliasing.cpp:159:9:159:9 | s indirection [data] |
| aliasing.cpp:159:9:159:9 | s indirection [data] | aliasing.cpp:159:8:159:14 | * ... |
-| aliasing.cpp:159:9:159:9 | s indirection [data] | aliasing.cpp:159:9:159:14 | data indirection |
-| aliasing.cpp:159:9:159:14 | data indirection | aliasing.cpp:159:8:159:14 | * ... |
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument | aliasing.cpp:164:17:164:20 | s indirection [post update] [data] |
| aliasing.cpp:164:17:164:20 | s indirection [post update] [data] | aliasing.cpp:165:8:165:8 | s indirection [data] |
| aliasing.cpp:165:8:165:8 | s indirection [data] | aliasing.cpp:165:8:165:16 | access to array |
-| aliasing.cpp:165:8:165:8 | s indirection [data] | aliasing.cpp:165:8:165:16 | access to array indirection |
-| aliasing.cpp:165:8:165:16 | access to array indirection | aliasing.cpp:165:8:165:16 | access to array |
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] |
| aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] | aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] |
| aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] | aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] |
| aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] | aliasing.cpp:176:11:176:11 | s indirection [m1] |
| aliasing.cpp:176:11:176:11 | s indirection [m1] | aliasing.cpp:176:13:176:14 | m1 |
-| aliasing.cpp:176:11:176:11 | s indirection [m1] | aliasing.cpp:176:13:176:14 | m1 indirection |
-| aliasing.cpp:176:13:176:14 | m1 indirection | aliasing.cpp:176:13:176:14 | m1 |
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] |
| aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] | aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] |
| aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] | aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] |
| aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] | aliasing.cpp:189:13:189:13 | s indirection [m1] |
| aliasing.cpp:189:13:189:13 | s indirection [m1] | aliasing.cpp:189:15:189:16 | m1 |
-| aliasing.cpp:189:13:189:13 | s indirection [m1] | aliasing.cpp:189:15:189:16 | m1 indirection |
-| aliasing.cpp:189:15:189:16 | m1 indirection | aliasing.cpp:189:15:189:16 | m1 |
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] |
| aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] | aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] |
| aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] | aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] |
| aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] | aliasing.cpp:201:13:201:13 | s indirection [m1] |
| aliasing.cpp:201:13:201:13 | s indirection [m1] | aliasing.cpp:201:15:201:16 | m1 |
-| aliasing.cpp:201:13:201:13 | s indirection [m1] | aliasing.cpp:201:15:201:16 | m1 indirection |
-| aliasing.cpp:201:15:201:16 | m1 indirection | aliasing.cpp:201:15:201:16 | m1 |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
@@ -380,14 +312,10 @@ edges
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... |
| arrays.cpp:37:8:37:8 | o indirection [nested, arr, data] | arrays.cpp:37:10:37:15 | nested indirection [arr, data] |
| arrays.cpp:37:8:37:22 | access to array indirection [data] | arrays.cpp:37:24:37:27 | data |
-| arrays.cpp:37:8:37:22 | access to array indirection [data] | arrays.cpp:37:24:37:27 | data indirection |
| arrays.cpp:37:10:37:15 | nested indirection [arr, data] | arrays.cpp:37:8:37:22 | access to array indirection [data] |
-| arrays.cpp:37:24:37:27 | data indirection | arrays.cpp:37:24:37:27 | data |
| arrays.cpp:38:8:38:8 | o indirection [nested, arr, data] | arrays.cpp:38:10:38:15 | nested indirection [arr, data] |
| arrays.cpp:38:8:38:22 | access to array indirection [data] | arrays.cpp:38:24:38:27 | data |
-| arrays.cpp:38:8:38:22 | access to array indirection [data] | arrays.cpp:38:24:38:27 | data indirection |
| arrays.cpp:38:10:38:15 | nested indirection [arr, data] | arrays.cpp:38:8:38:22 | access to array indirection [data] |
-| arrays.cpp:38:24:38:27 | data indirection | arrays.cpp:38:24:38:27 | data |
| arrays.cpp:42:3:42:40 | ... = ... | arrays.cpp:42:22:42:25 | access to array indirection [post update] [data] |
| arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] |
| arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] |
@@ -395,19 +323,13 @@ edges
| arrays.cpp:42:22:42:25 | access to array indirection [post update] [data] | arrays.cpp:42:15:42:17 | indirect indirection [post update] [arr, data] |
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... |
| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
-| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data |
-| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data indirection |
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:8:43:25 | access to array indirection [data] |
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
-| arrays.cpp:43:27:43:30 | data indirection | arrays.cpp:43:27:43:30 | data |
-| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data |
-| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data indirection |
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:8:44:25 | access to array indirection [data] |
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
-| arrays.cpp:44:27:44:30 | data indirection | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:48:3:48:40 | ... = ... | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] |
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] |
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] |
@@ -415,23 +337,17 @@ edges
| arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] | arrays.cpp:48:15:48:17 | indirect indirection [post update] [ptr indirection, data] |
| arrays.cpp:48:29:48:38 | call to user_input | arrays.cpp:48:3:48:40 | ... = ... |
| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
-| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data |
-| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data indirection |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:20:49:22 | ptr indirection [data] |
| arrays.cpp:49:20:49:22 | ptr indirection [data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
-| arrays.cpp:49:27:49:30 | data indirection | arrays.cpp:49:27:49:30 | data |
-| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data |
-| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data indirection |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:20:50:22 | ptr indirection [data] |
| arrays.cpp:50:20:50:22 | ptr indirection [data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
-| arrays.cpp:50:27:50:30 | data indirection | arrays.cpp:50:27:50:30 | data |
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:8:12:8 | s indirection [post update] [a] |
| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... |
@@ -444,14 +360,10 @@ edges
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
| by_reference.cpp:31:46:31:46 | s indirection [a] | by_reference.cpp:32:12:32:12 | s indirection [a] |
| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a |
-| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a indirection |
| by_reference.cpp:32:15:32:15 | a | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection |
-| by_reference.cpp:32:15:32:15 | a indirection | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection |
| by_reference.cpp:35:9:35:19 | this indirection [a] | by_reference.cpp:36:12:36:15 | this indirection [a] |
| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a |
-| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a indirection |
| by_reference.cpp:36:18:36:18 | a | by_reference.cpp:35:9:35:19 | getDirectly indirection |
-| by_reference.cpp:36:18:36:18 | a indirection | by_reference.cpp:35:9:35:19 | getDirectly indirection |
| by_reference.cpp:39:9:39:21 | this indirection [a] | by_reference.cpp:40:12:40:15 | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:40:18:40:28 | call to getDirectly |
@@ -512,30 +424,16 @@ edges
| by_reference.cpp:108:24:108:24 | pouter indirection [post update] [a] | by_reference.cpp:116:8:116:13 | pouter indirection [a] |
| by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] |
| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a |
-| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a indirection |
-| by_reference.cpp:110:27:110:27 | a indirection | by_reference.cpp:110:27:110:27 | a |
-| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a |
-| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a indirection |
-| by_reference.cpp:111:25:111:25 | a indirection | by_reference.cpp:111:25:111:25 | a |
| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a |
-| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a indirection |
-| by_reference.cpp:112:14:112:14 | a indirection | by_reference.cpp:112:14:112:14 | a |
| by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] |
| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a |
-| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a indirection |
-| by_reference.cpp:114:29:114:29 | a indirection | by_reference.cpp:114:29:114:29 | a |
-| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a |
-| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a indirection |
-| by_reference.cpp:115:27:115:27 | a indirection | by_reference.cpp:115:27:115:27 | a |
| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a |
-| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a indirection |
-| by_reference.cpp:116:16:116:16 | a indirection | by_reference.cpp:116:16:116:16 | a |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] |
| by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | by_reference.cpp:123:28:123:36 | outer indirection [post update] [inner_ptr indirection, a] |
@@ -550,39 +448,21 @@ edges
| by_reference.cpp:128:23:128:23 | pouter indirection [post update] [a] | by_reference.cpp:136:8:136:13 | pouter indirection [a] |
| by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] |
| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a |
-| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a indirection |
-| by_reference.cpp:130:27:130:27 | a indirection | by_reference.cpp:130:27:130:27 | a |
-| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a |
-| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a indirection |
-| by_reference.cpp:131:25:131:25 | a indirection | by_reference.cpp:131:25:131:25 | a |
| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a |
-| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a indirection |
-| by_reference.cpp:132:14:132:14 | a indirection | by_reference.cpp:132:14:132:14 | a |
| by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] |
| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a |
-| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a indirection |
-| by_reference.cpp:134:29:134:29 | a indirection | by_reference.cpp:134:29:134:29 | a |
-| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a |
-| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a indirection |
-| by_reference.cpp:135:27:135:27 | a indirection | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a |
-| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a indirection |
-| by_reference.cpp:136:16:136:16 | a indirection | by_reference.cpp:136:16:136:16 | a |
| clearning.cpp:32:3:32:25 | ... = ... | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] |
| clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] | clearning.cpp:33:5:33:5 | s indirection [x indirection] |
| clearning.cpp:32:10:32:19 | call to user_input | clearning.cpp:32:3:32:25 | ... = ... |
| clearning.cpp:33:5:33:5 | s indirection [x indirection] | clearning.cpp:34:9:34:9 | s indirection [x indirection] |
| clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:8:34:11 | * ... |
-| clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:11:34:11 | x indirection |
-| clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:11:34:11 | x indirection |
-| clearning.cpp:34:11:34:11 | x indirection | clearning.cpp:34:8:34:11 | * ... |
-| clearning.cpp:34:11:34:11 | x indirection | clearning.cpp:34:8:34:11 | * ... |
| clearning.cpp:53:3:53:25 | ... = ... | clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] |
| clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] | clearning.cpp:54:3:54:3 | s indirection [x indirection] |
| clearning.cpp:53:10:53:19 | call to user_input | clearning.cpp:53:3:53:25 | ... = ... |
@@ -596,6 +476,7 @@ edges
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
+| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:60:3:60:22 | ... = ... | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] |
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | clearning.cpp:61:3:61:3 | s indirection [x indirection] |
| clearning.cpp:60:11:60:20 | call to user_input | clearning.cpp:60:3:60:22 | ... = ... |
@@ -609,13 +490,10 @@ edges
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
+| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:74:20:74:22 | argument_source output argument | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] |
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | clearning.cpp:76:8:76:8 | s indirection [val indirection] |
| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:7:76:12 | * ... |
-| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:10:76:12 | val indirection |
-| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:10:76:12 | val indirection |
-| clearning.cpp:76:10:76:12 | val indirection | clearning.cpp:76:7:76:12 | * ... |
-| clearning.cpp:76:10:76:12 | val indirection | clearning.cpp:76:7:76:12 | * ... |
| clearning.cpp:81:20:81:22 | argument_source output argument | clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] |
| clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] | clearning.cpp:83:13:83:13 | s indirection [val indirection] |
| clearning.cpp:83:5:83:21 | ... = ... indirection | clearning.cpp:83:7:83:9 | s indirection [post update] [val indirection] |
@@ -625,10 +503,6 @@ edges
| clearning.cpp:83:13:83:21 | ... + ... indirection | clearning.cpp:83:5:83:21 | ... = ... indirection |
| clearning.cpp:83:15:83:17 | val indirection | clearning.cpp:83:5:83:21 | ... = ... indirection |
| clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:7:84:12 | * ... |
-| clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:10:84:12 | val indirection |
-| clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:10:84:12 | val indirection |
-| clearning.cpp:84:10:84:12 | val indirection | clearning.cpp:84:7:84:12 | * ... |
-| clearning.cpp:84:10:84:12 | val indirection | clearning.cpp:84:7:84:12 | * ... |
| clearning.cpp:89:20:89:22 | argument_source output argument | clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] |
| clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] | clearning.cpp:90:3:90:3 | s indirection [val indirection] |
| clearning.cpp:90:3:90:3 | s indirection [val indirection] | clearning.cpp:90:3:90:9 | ... ++ indirection |
@@ -639,10 +513,6 @@ edges
| clearning.cpp:90:5:90:7 | s indirection [post update] [val indirection] | clearning.cpp:91:8:91:8 | s indirection [val indirection] |
| clearning.cpp:90:5:90:7 | val indirection | clearning.cpp:90:3:90:9 | ... ++ indirection |
| clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:7:91:12 | * ... |
-| clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:10:91:12 | val indirection |
-| clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:10:91:12 | val indirection |
-| clearning.cpp:91:10:91:12 | val indirection | clearning.cpp:91:7:91:12 | * ... |
-| clearning.cpp:91:10:91:12 | val indirection | clearning.cpp:91:7:91:12 | * ... |
| clearning.cpp:96:20:96:22 | argument_source output argument | clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] |
| clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] | clearning.cpp:97:10:97:10 | s indirection [val indirection] |
| clearning.cpp:97:2:97:18 | ... = ... indirection | clearning.cpp:97:4:97:6 | s indirection [post update] [val indirection] |
@@ -652,10 +522,6 @@ edges
| clearning.cpp:97:10:97:18 | ... + ... indirection | clearning.cpp:97:2:97:18 | ... = ... indirection |
| clearning.cpp:97:12:97:14 | val indirection | clearning.cpp:97:2:97:18 | ... = ... indirection |
| clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:7:98:12 | * ... |
-| clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:10:98:12 | val indirection |
-| clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:10:98:12 | val indirection |
-| clearning.cpp:98:10:98:12 | val indirection | clearning.cpp:98:7:98:12 | * ... |
-| clearning.cpp:98:10:98:12 | val indirection | clearning.cpp:98:7:98:12 | * ... |
| clearning.cpp:103:20:103:22 | argument_source output argument | clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] |
| clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] | clearning.cpp:104:2:104:2 | s indirection [val indirection] |
| clearning.cpp:104:2:104:2 | s indirection [val indirection] | clearning.cpp:104:2:104:8 | ... ++ indirection |
@@ -666,10 +532,6 @@ edges
| clearning.cpp:104:4:104:6 | s indirection [post update] [val indirection] | clearning.cpp:105:8:105:8 | s indirection [val indirection] |
| clearning.cpp:104:4:104:6 | val indirection | clearning.cpp:104:2:104:8 | ... ++ indirection |
| clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:7:105:12 | * ... |
-| clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:10:105:12 | val indirection |
-| clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:10:105:12 | val indirection |
-| clearning.cpp:105:10:105:12 | val indirection | clearning.cpp:105:7:105:12 | * ... |
-| clearning.cpp:105:10:105:12 | val indirection | clearning.cpp:105:7:105:12 | * ... |
| clearning.cpp:110:20:110:22 | argument_source output argument | clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] |
| clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] | clearning.cpp:111:4:111:4 | s indirection [val indirection] |
| clearning.cpp:111:2:111:8 | ++ ... indirection | clearning.cpp:111:2:111:8 | ++ ... indirection |
@@ -680,10 +542,6 @@ edges
| clearning.cpp:111:6:111:8 | s indirection [post update] [val indirection] | clearning.cpp:112:8:112:8 | s indirection [val indirection] |
| clearning.cpp:111:6:111:8 | val indirection | clearning.cpp:111:2:111:8 | ++ ... indirection |
| clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:7:112:12 | * ... |
-| clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:10:112:12 | val indirection |
-| clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:10:112:12 | val indirection |
-| clearning.cpp:112:10:112:12 | val indirection | clearning.cpp:112:7:112:12 | * ... |
-| clearning.cpp:112:10:112:12 | val indirection | clearning.cpp:112:7:112:12 | * ... |
| clearning.cpp:117:20:117:22 | argument_source output argument | clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] |
| clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] | clearning.cpp:118:2:118:2 | s indirection [val indirection] |
| clearning.cpp:118:2:118:2 | s indirection [val indirection] | clearning.cpp:118:2:118:11 | ... += ... indirection |
@@ -694,26 +552,16 @@ edges
| clearning.cpp:118:4:118:6 | s indirection [post update] [val indirection] | clearning.cpp:119:8:119:8 | s indirection [val indirection] |
| clearning.cpp:118:4:118:6 | val indirection | clearning.cpp:118:2:118:11 | ... += ... indirection |
| clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:7:119:12 | * ... |
-| clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:10:119:12 | val indirection |
-| clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:10:119:12 | val indirection |
-| clearning.cpp:119:10:119:12 | val indirection | clearning.cpp:119:7:119:12 | * ... |
-| clearning.cpp:119:10:119:12 | val indirection | clearning.cpp:119:7:119:12 | * ... |
| clearning.cpp:151:3:151:22 | ... = ... | clearning.cpp:151:5:151:7 | s indirection [post update] [val] |
| clearning.cpp:151:5:151:7 | s indirection [post update] [val] | clearning.cpp:152:8:152:8 | s indirection [val] |
| clearning.cpp:151:11:151:20 | call to user_input | clearning.cpp:151:3:151:22 | ... = ... |
| clearning.cpp:152:8:152:8 | s indirection [val] | clearning.cpp:152:10:152:12 | val |
-| clearning.cpp:152:8:152:8 | s indirection [val] | clearning.cpp:152:10:152:12 | val indirection |
-| clearning.cpp:152:10:152:12 | val indirection | clearning.cpp:152:10:152:12 | val |
| complex.cpp:9:7:9:7 | this indirection [a_] | complex.cpp:9:20:9:21 | this indirection [a_] |
| complex.cpp:9:20:9:21 | a_ | complex.cpp:9:7:9:7 | a indirection |
-| complex.cpp:9:20:9:21 | a_ indirection | complex.cpp:9:7:9:7 | a indirection |
| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ |
-| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ indirection |
| complex.cpp:10:7:10:7 | this indirection [b_] | complex.cpp:10:20:10:21 | this indirection [b_] |
| complex.cpp:10:20:10:21 | b_ | complex.cpp:10:7:10:7 | b indirection |
-| complex.cpp:10:20:10:21 | b_ indirection | complex.cpp:10:7:10:7 | b indirection |
| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ |
-| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ indirection |
| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... |
| complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | this indirection [post update] [a_] |
| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | ... = ... |
@@ -772,55 +620,36 @@ edges
| conflated.cpp:10:7:10:7 | ra indirection [post update] [p indirection] | conflated.cpp:11:9:11:10 | ra indirection [p indirection] |
| conflated.cpp:10:11:10:20 | call to user_input | conflated.cpp:10:3:10:22 | ... = ... |
| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:8:11:12 | * ... |
-| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:12:11:12 | p indirection |
-| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:12:11:12 | p indirection |
-| conflated.cpp:11:12:11:12 | p indirection | conflated.cpp:11:8:11:12 | * ... |
-| conflated.cpp:11:12:11:12 | p indirection | conflated.cpp:11:8:11:12 | * ... |
-| conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection |
| conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection |
| conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection |
| conflated.cpp:29:3:29:22 | ... = ... | conflated.cpp:29:7:29:7 | pa indirection [post update] [x] |
| conflated.cpp:29:7:29:7 | pa indirection [post update] [x] | conflated.cpp:30:8:30:9 | pa indirection [x] |
| conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:29:3:29:22 | ... = ... |
| conflated.cpp:30:8:30:9 | pa indirection [x] | conflated.cpp:30:12:30:12 | x |
-| conflated.cpp:30:8:30:9 | pa indirection [x] | conflated.cpp:30:12:30:12 | x indirection |
-| conflated.cpp:30:12:30:12 | x indirection | conflated.cpp:30:12:30:12 | x |
| conflated.cpp:36:3:36:22 | ... = ... | conflated.cpp:36:7:36:7 | pa indirection [post update] [x] |
| conflated.cpp:36:7:36:7 | pa indirection [post update] [x] | conflated.cpp:37:8:37:9 | pa indirection [x] |
| conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:36:3:36:22 | ... = ... |
| conflated.cpp:37:8:37:9 | pa indirection [x] | conflated.cpp:37:12:37:12 | x |
-| conflated.cpp:37:8:37:9 | pa indirection [x] | conflated.cpp:37:12:37:12 | x indirection |
-| conflated.cpp:37:12:37:12 | x indirection | conflated.cpp:37:12:37:12 | x |
| conflated.cpp:54:3:54:28 | ... = ... | conflated.cpp:54:13:54:13 | next indirection [post update] [y] |
| conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] |
| conflated.cpp:54:13:54:13 | next indirection [post update] [y] | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] |
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] |
-| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] |
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:12:55:15 | next indirection [y] |
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y |
-| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y indirection |
-| conflated.cpp:55:18:55:18 | y indirection | conflated.cpp:55:18:55:18 | y |
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:13:60:13 | next indirection [post update] [y] |
| conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] |
| conflated.cpp:60:13:60:13 | next indirection [post update] [y] | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] |
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] |
-| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] |
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:12:61:15 | next indirection [y] |
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y |
-| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y indirection |
-| conflated.cpp:61:18:61:18 | y indirection | conflated.cpp:61:18:61:18 | y |
| constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] |
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection |
-| constructors.cpp:18:22:18:23 | a_ indirection | constructors.cpp:18:9:18:9 | a indirection |
| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ |
-| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ indirection |
| constructors.cpp:19:9:19:9 | this indirection [b_] | constructors.cpp:19:22:19:23 | this indirection [b_] |
| constructors.cpp:19:22:19:23 | b_ | constructors.cpp:19:9:19:9 | b indirection |
-| constructors.cpp:19:22:19:23 | b_ indirection | constructors.cpp:19:9:19:9 | b indirection |
| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ |
-| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ indirection |
| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a |
| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b |
| constructors.cpp:23:28:23:28 | a | constructors.cpp:23:25:23:29 | this indirection [post update] [a_] |
@@ -858,61 +687,43 @@ edges
| qualifiers.cpp:22:23:22:23 | call to getInner indirection [post update] [a] | qualifiers.cpp:22:5:22:9 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
-| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a |
-| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a indirection |
-| qualifiers.cpp:23:23:23:23 | a indirection | qualifiers.cpp:23:23:23:23 | a |
| qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:27:11:27:18 | setA output argument [a] | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | setA output argument [a] |
| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
-| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a |
-| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a indirection |
-| qualifiers.cpp:28:23:28:23 | a indirection | qualifiers.cpp:28:23:28:23 | a |
| qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
-| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a |
-| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a indirection |
-| qualifiers.cpp:33:23:33:23 | a indirection | qualifiers.cpp:33:23:33:23 | a |
| qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
-| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a |
-| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a indirection |
-| qualifiers.cpp:38:23:38:23 | a indirection | qualifiers.cpp:38:23:38:23 | a |
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] |
| qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
-| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a |
-| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a indirection |
-| qualifiers.cpp:43:23:43:23 | a indirection | qualifiers.cpp:43:23:43:23 | a |
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] |
| qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
-| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a |
-| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a indirection |
-| qualifiers.cpp:48:23:48:23 | a indirection | qualifiers.cpp:48:23:48:23 | a |
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:35:53:43 | userInput indirection [post update] [bufferLen] |
| realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] |
| realistic.cpp:53:20:53:22 | access to array indirection [post update] [baz indirection, userInput, bufferLen] | realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] |
@@ -922,23 +733,16 @@ edges
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
| realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
-| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] |
| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:14:61:55 | bufferLen |
-| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen indirection |
-| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:14:61:55 | bufferLen |
-| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:47:61:55 | bufferLen |
+| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
| simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] |
| simple.cpp:18:22:18:23 | a_ | simple.cpp:18:9:18:9 | a indirection |
-| simple.cpp:18:22:18:23 | a_ indirection | simple.cpp:18:9:18:9 | a indirection |
| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ |
-| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ indirection |
| simple.cpp:19:9:19:9 | this indirection [b_] | simple.cpp:19:22:19:23 | this indirection [b_] |
| simple.cpp:19:22:19:23 | b_ | simple.cpp:19:9:19:9 | b indirection |
-| simple.cpp:19:22:19:23 | b_ indirection | simple.cpp:19:9:19:9 | b indirection |
| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ |
-| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ indirection |
| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... |
| simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | this indirection [post update] [a_] |
| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | ... = ... |
@@ -969,14 +773,10 @@ edges
| simple.cpp:65:7:65:7 | a indirection [post update] [i] | simple.cpp:67:10:67:11 | a2 indirection [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... |
| simple.cpp:67:10:67:11 | a2 indirection [i] | simple.cpp:67:13:67:13 | i |
-| simple.cpp:67:10:67:11 | a2 indirection [i] | simple.cpp:67:13:67:13 | i indirection |
-| simple.cpp:67:13:67:13 | i indirection | simple.cpp:67:13:67:13 | i |
| simple.cpp:78:9:78:15 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | this indirection [f2, f1] |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 |
-| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 indirection |
| simple.cpp:79:16:79:17 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | f2 indirection [f1] |
| simple.cpp:79:19:79:20 | f1 | simple.cpp:78:9:78:15 | getf2f1 indirection |
-| simple.cpp:79:19:79:20 | f1 indirection | simple.cpp:78:9:78:15 | getf2f1 indirection |
| simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | simple.cpp:84:14:84:20 | this indirection [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] |
| simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] | simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] |
@@ -987,12 +787,8 @@ edges
| simple.cpp:92:7:92:7 | a indirection [post update] [i] | simple.cpp:94:10:94:11 | a2 indirection [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... |
| simple.cpp:94:10:94:11 | a2 indirection [i] | simple.cpp:94:13:94:13 | i |
-| simple.cpp:94:10:94:11 | a2 indirection [i] | simple.cpp:94:13:94:13 | i indirection |
-| simple.cpp:94:13:94:13 | i indirection | simple.cpp:94:13:94:13 | i |
| struct_init.c:14:24:14:25 | ab indirection [a] | struct_init.c:15:8:15:9 | ab indirection [a] |
| struct_init.c:15:8:15:9 | ab indirection [a] | struct_init.c:15:12:15:12 | a |
-| struct_init.c:15:8:15:9 | ab indirection [a] | struct_init.c:15:12:15:12 | a indirection |
-| struct_init.c:15:12:15:12 | a indirection | struct_init.c:15:12:15:12 | a |
| struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:22:8:22:9 | ab indirection [a] |
| struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:24:10:24:12 | & ... indirection [a] |
| struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:28:5:28:7 | & ... indirection [a] |
@@ -1000,8 +796,6 @@ edges
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | definition of ab indirection [post update] [a] |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | call to user_input |
| struct_init.c:22:8:22:9 | ab indirection [a] | struct_init.c:22:11:22:11 | a |
-| struct_init.c:22:8:22:9 | ab indirection [a] | struct_init.c:22:11:22:11 | a indirection |
-| struct_init.c:22:11:22:11 | a indirection | struct_init.c:22:11:22:11 | a |
| struct_init.c:24:10:24:12 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
| struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] |
| struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] |
@@ -1015,14 +809,9 @@ edges
| struct_init.c:28:5:28:7 | & ... indirection [a] | struct_init.c:26:23:29:3 | definition of outer indirection [post update] [pointerAB indirection, a] |
| struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB indirection [a] |
| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a |
-| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a indirection |
-| struct_init.c:31:23:31:23 | a indirection | struct_init.c:31:23:31:23 | a |
-| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a |
-| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a indirection |
-| struct_init.c:33:25:33:25 | a indirection | struct_init.c:33:25:33:25 | a |
| struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
| struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | struct_init.c:36:10:36:24 | & ... indirection [a] |
| struct_init.c:40:13:40:14 | definition of ab indirection [a] | struct_init.c:43:5:43:7 | & ... indirection [a] |
@@ -1032,7 +821,6 @@ edges
| struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] | struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] |
| struct_init.c:43:5:43:7 | & ... indirection [a] | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] |
| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
-| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
nodes
@@ -1046,7 +834,6 @@ nodes
| A.cpp:28:8:28:10 | this indirection [c] | semmle.label | this indirection [c] |
| A.cpp:28:23:28:26 | this indirection [c] | semmle.label | this indirection [c] |
| A.cpp:28:29:28:29 | c | semmle.label | c |
-| A.cpp:28:29:28:29 | c indirection | semmle.label | c indirection |
| A.cpp:29:15:29:18 | make indirection [c] | semmle.label | make indirection [c] |
| A.cpp:29:23:29:23 | c | semmle.label | c |
| A.cpp:31:14:31:21 | call to B [c] | semmle.label | call to B [c] |
@@ -1061,7 +848,6 @@ nodes
| A.cpp:49:10:49:10 | b indirection [c] | semmle.label | b indirection [c] |
| A.cpp:49:10:49:13 | c | semmle.label | c |
| A.cpp:49:13:49:13 | c | semmle.label | c |
-| A.cpp:49:13:49:13 | c indirection | semmle.label | c indirection |
| A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] |
| A.cpp:55:12:55:19 | new | semmle.label | new |
| A.cpp:55:12:55:19 | new | semmle.label | new |
@@ -1078,14 +864,12 @@ nodes
| A.cpp:66:10:66:11 | b2 indirection [c] | semmle.label | b2 indirection [c] |
| A.cpp:66:10:66:14 | c | semmle.label | c |
| A.cpp:66:14:66:14 | c | semmle.label | c |
-| A.cpp:66:14:66:14 | c indirection | semmle.label | c indirection |
| A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] | semmle.label | call to setOnBWrap indirection [c] |
| A.cpp:73:25:73:32 | new | semmle.label | new |
| A.cpp:73:25:73:32 | new | semmle.label | new |
| A.cpp:75:10:75:11 | b2 indirection [c] | semmle.label | b2 indirection [c] |
| A.cpp:75:10:75:14 | c | semmle.label | c |
| A.cpp:75:14:75:14 | c | semmle.label | c |
-| A.cpp:75:14:75:14 | c indirection | semmle.label | c indirection |
| A.cpp:78:6:78:15 | setOnBWrap indirection [c] | semmle.label | setOnBWrap indirection [c] |
| A.cpp:78:27:78:27 | c | semmle.label | c |
| A.cpp:81:10:81:15 | call to setOnB indirection [c] | semmle.label | call to setOnB indirection [c] |
@@ -1102,11 +886,9 @@ nodes
| A.cpp:107:12:107:13 | c1 indirection [a] | semmle.label | c1 indirection [a] |
| A.cpp:107:12:107:16 | a | semmle.label | a |
| A.cpp:107:16:107:16 | a | semmle.label | a |
-| A.cpp:107:16:107:16 | a indirection | semmle.label | a indirection |
| A.cpp:120:12:120:13 | c1 indirection [a] | semmle.label | c1 indirection [a] |
| A.cpp:120:12:120:16 | a | semmle.label | a |
| A.cpp:120:16:120:16 | a | semmle.label | a |
-| A.cpp:120:16:120:16 | a indirection | semmle.label | a indirection |
| A.cpp:126:5:126:5 | set output argument [c] | semmle.label | set output argument [c] |
| A.cpp:126:12:126:18 | new | semmle.label | new |
| A.cpp:126:12:126:18 | new | semmle.label | new |
@@ -1114,7 +896,6 @@ nodes
| A.cpp:132:10:132:10 | b indirection [c] | semmle.label | b indirection [c] |
| A.cpp:132:10:132:13 | c | semmle.label | c |
| A.cpp:132:13:132:13 | c | semmle.label | c |
-| A.cpp:132:13:132:13 | c indirection | semmle.label | c indirection |
| A.cpp:140:13:140:13 | b | semmle.label | b |
| A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... |
| A.cpp:142:10:142:10 | b indirection [post update] [c] | semmle.label | b indirection [post update] [c] |
@@ -1134,17 +915,13 @@ nodes
| A.cpp:152:10:152:10 | d indirection [b] | semmle.label | d indirection [b] |
| A.cpp:152:10:152:13 | b | semmle.label | b |
| A.cpp:152:13:152:13 | b | semmle.label | b |
-| A.cpp:152:13:152:13 | b indirection | semmle.label | b indirection |
| A.cpp:153:10:153:10 | d indirection [b indirection, c] | semmle.label | d indirection [b indirection, c] |
| A.cpp:153:10:153:16 | c | semmle.label | c |
| A.cpp:153:13:153:13 | b indirection [c] | semmle.label | b indirection [c] |
-| A.cpp:153:13:153:13 | b indirection [c] | semmle.label | b indirection [c] |
| A.cpp:153:16:153:16 | c | semmle.label | c |
-| A.cpp:153:16:153:16 | c indirection | semmle.label | c indirection |
| A.cpp:154:10:154:10 | b indirection [c] | semmle.label | b indirection [c] |
| A.cpp:154:10:154:13 | c | semmle.label | c |
| A.cpp:154:13:154:13 | c | semmle.label | c |
-| A.cpp:154:13:154:13 | c indirection | semmle.label | c indirection |
| A.cpp:159:12:159:18 | new | semmle.label | new |
| A.cpp:160:18:160:60 | call to MyList [head] | semmle.label | call to MyList [head] |
| A.cpp:160:29:160:29 | b | semmle.label | b |
@@ -1155,21 +932,15 @@ nodes
| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | semmle.label | l3 indirection [next indirection, next indirection, head] |
| A.cpp:165:10:165:29 | head | semmle.label | head |
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] |
-| A.cpp:165:14:165:17 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] |
-| A.cpp:165:20:165:23 | next indirection [head] | semmle.label | next indirection [head] |
| A.cpp:165:20:165:23 | next indirection [head] | semmle.label | next indirection [head] |
| A.cpp:165:26:165:29 | head | semmle.label | head |
-| A.cpp:165:26:165:29 | head indirection | semmle.label | head indirection |
| A.cpp:167:44:167:44 | l indirection [next indirection, head] | semmle.label | l indirection [next indirection, head] |
| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | semmle.label | l indirection [next indirection, next indirection, head] |
| A.cpp:167:47:167:50 | next indirection [head] | semmle.label | next indirection [head] |
-| A.cpp:167:47:167:50 | next indirection [head] | semmle.label | next indirection [head] |
-| A.cpp:167:47:167:50 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] |
| A.cpp:167:47:167:50 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] |
| A.cpp:169:12:169:12 | l indirection [head] | semmle.label | l indirection [head] |
| A.cpp:169:12:169:18 | head | semmle.label | head |
| A.cpp:169:15:169:18 | head | semmle.label | head |
-| A.cpp:169:15:169:18 | head indirection | semmle.label | head indirection |
| A.cpp:181:15:181:21 | newHead | semmle.label | newHead |
| A.cpp:181:32:181:35 | next indirection [head] | semmle.label | next indirection [head] |
| A.cpp:181:32:181:35 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] |
@@ -1187,9 +958,7 @@ nodes
| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | semmle.label | b2 indirection [box1 indirection, elem1] |
| B.cpp:9:10:9:24 | elem1 | semmle.label | elem1 |
| B.cpp:9:14:9:17 | box1 indirection [elem1] | semmle.label | box1 indirection [elem1] |
-| B.cpp:9:14:9:17 | box1 indirection [elem1] | semmle.label | box1 indirection [elem1] |
| B.cpp:9:20:9:24 | elem1 | semmle.label | elem1 |
-| B.cpp:9:20:9:24 | elem1 indirection | semmle.label | elem1 indirection |
| B.cpp:15:15:15:27 | new | semmle.label | new |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | semmle.label | call to Box1 [elem2] |
| B.cpp:16:37:16:37 | e | semmle.label | e |
@@ -1198,9 +967,7 @@ nodes
| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | semmle.label | b2 indirection [box1 indirection, elem2] |
| B.cpp:19:10:19:24 | elem2 | semmle.label | elem2 |
| B.cpp:19:14:19:17 | box1 indirection [elem2] | semmle.label | box1 indirection [elem2] |
-| B.cpp:19:14:19:17 | box1 indirection [elem2] | semmle.label | box1 indirection [elem2] |
| B.cpp:19:20:19:24 | elem2 | semmle.label | elem2 |
-| B.cpp:19:20:19:24 | elem2 indirection | semmle.label | elem2 indirection |
| B.cpp:33:16:33:17 | e1 | semmle.label | e1 |
| B.cpp:33:26:33:27 | e2 | semmle.label | e2 |
| B.cpp:35:7:35:22 | ... = ... | semmle.label | ... = ... |
@@ -1226,15 +993,12 @@ nodes
| C.cpp:27:8:27:11 | this indirection [s1] | semmle.label | this indirection [s1] |
| C.cpp:27:8:27:11 | this indirection [s3] | semmle.label | this indirection [s3] |
| C.cpp:29:10:29:11 | s1 | semmle.label | s1 |
-| C.cpp:29:10:29:11 | s1 indirection | semmle.label | s1 indirection |
| C.cpp:29:10:29:11 | this indirection [s1] | semmle.label | this indirection [s1] |
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
-| C.cpp:31:10:31:11 | s3 indirection | semmle.label | s3 indirection |
| C.cpp:31:10:31:11 | this indirection [s3] | semmle.label | this indirection [s3] |
| D.cpp:10:11:10:17 | getElem indirection | semmle.label | getElem indirection |
| D.cpp:10:11:10:17 | this indirection [elem] | semmle.label | this indirection [elem] |
| D.cpp:10:30:10:33 | elem | semmle.label | elem |
-| D.cpp:10:30:10:33 | elem indirection | semmle.label | elem indirection |
| D.cpp:10:30:10:33 | this indirection [elem] | semmle.label | this indirection [elem] |
| D.cpp:11:24:11:24 | e | semmle.label | e |
| D.cpp:11:29:11:32 | this indirection [post update] [elem] | semmle.label | this indirection [post update] [elem] |
@@ -1242,7 +1006,6 @@ nodes
| D.cpp:17:11:17:17 | getBox1 indirection [elem] | semmle.label | getBox1 indirection [elem] |
| D.cpp:17:11:17:17 | this indirection [box indirection, elem] | semmle.label | this indirection [box indirection, elem] |
| D.cpp:17:30:17:32 | box indirection [elem] | semmle.label | box indirection [elem] |
-| D.cpp:17:30:17:32 | box indirection [elem] | semmle.label | box indirection [elem] |
| D.cpp:17:30:17:32 | this indirection [box indirection, elem] | semmle.label | this indirection [box indirection, elem] |
| D.cpp:21:30:21:31 | b2 indirection [box indirection, elem] | semmle.label | b2 indirection [box indirection, elem] |
| D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] | semmle.label | b2 indirection [box indirection, elem] |
@@ -1276,13 +1039,10 @@ nodes
| D.cpp:59:5:59:7 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | semmle.label | boxfield indirection [box indirection, elem] |
-| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | semmle.label | boxfield indirection [box indirection, elem] |
| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:64:10:64:28 | elem | semmle.label | elem |
| D.cpp:64:20:64:22 | box indirection [elem] | semmle.label | box indirection [elem] |
-| D.cpp:64:20:64:22 | box indirection [elem] | semmle.label | box indirection [elem] |
| D.cpp:64:25:64:28 | elem | semmle.label | elem |
-| D.cpp:64:25:64:28 | elem indirection | semmle.label | elem indirection |
| E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] |
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | semmle.label | data indirection [buffer indirection] |
@@ -1295,7 +1055,6 @@ nodes
| E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] | semmle.label | p indirection [post update] [data, buffer indirection] |
| E.cpp:30:28:30:33 | data indirection [post update] [buffer indirection] | semmle.label | data indirection [post update] [buffer indirection] |
| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection |
-| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection |
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | semmle.label | b indirection [buffer indirection] |
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
@@ -1310,16 +1069,13 @@ nodes
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | semmle.label | referenceSetter output argument [m1] |
| aliasing.cpp:29:8:29:9 | s1 indirection [m1] | semmle.label | s1 indirection [m1] |
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
-| aliasing.cpp:29:11:29:12 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:30:8:30:9 | s2 indirection [m1] | semmle.label | s2 indirection [m1] |
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
-| aliasing.cpp:30:11:30:12 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] | semmle.label | s2 indirection [post update] [m1] |
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | semmle.label | copy2 indirection [m1] |
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
-| aliasing.cpp:62:14:62:15 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:92:3:92:23 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] | semmle.label | w indirection [post update] [s, m1] |
| aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
@@ -1327,7 +1083,6 @@ nodes
| aliasing.cpp:93:8:93:8 | w indirection [s, m1] | semmle.label | w indirection [s, m1] |
| aliasing.cpp:93:10:93:10 | s indirection [m1] | semmle.label | s indirection [m1] |
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
-| aliasing.cpp:93:12:93:13 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:98:3:98:21 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
| aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input |
@@ -1348,39 +1103,33 @@ nodes
| aliasing.cpp:141:17:141:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:143:8:143:8 | s indirection [data indirection] | semmle.label | s indirection [data indirection] |
| aliasing.cpp:143:8:143:16 | access to array | semmle.label | access to array |
-| aliasing.cpp:143:8:143:16 | access to array indirection | semmle.label | access to array indirection |
| aliasing.cpp:143:10:143:13 | data indirection | semmle.label | data indirection |
| aliasing.cpp:158:15:158:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:158:17:158:20 | s indirection [post update] [data] | semmle.label | s indirection [post update] [data] |
| aliasing.cpp:159:8:159:14 | * ... | semmle.label | * ... |
| aliasing.cpp:159:9:159:9 | s indirection [data] | semmle.label | s indirection [data] |
-| aliasing.cpp:159:9:159:14 | data indirection | semmle.label | data indirection |
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:164:17:164:20 | s indirection [post update] [data] | semmle.label | s indirection [post update] [data] |
| aliasing.cpp:165:8:165:8 | s indirection [data] | semmle.label | s indirection [data] |
| aliasing.cpp:165:8:165:16 | access to array | semmle.label | access to array |
-| aliasing.cpp:165:8:165:16 | access to array indirection | semmle.label | access to array indirection |
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] | semmle.label | s2 indirection [post update] [s, m1] |
| aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
| aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] | semmle.label | s2 indirection [s, m1] |
| aliasing.cpp:176:11:176:11 | s indirection [m1] | semmle.label | s indirection [m1] |
| aliasing.cpp:176:13:176:14 | m1 | semmle.label | m1 |
-| aliasing.cpp:176:13:176:14 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] | semmle.label | s2 indirection [post update] [s, m1] |
| aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
| aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] | semmle.label | s2_2 indirection [s, m1] |
| aliasing.cpp:189:13:189:13 | s indirection [m1] | semmle.label | s indirection [m1] |
| aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 |
-| aliasing.cpp:189:15:189:16 | m1 indirection | semmle.label | m1 indirection |
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
| aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] | semmle.label | ps2 indirection [post update] [s, m1] |
| aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
| aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] | semmle.label | ps2 indirection [s, m1] |
| aliasing.cpp:201:13:201:13 | s indirection [m1] | semmle.label | s indirection [m1] |
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
-| aliasing.cpp:201:15:201:16 | m1 indirection | semmle.label | m1 indirection |
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
| arrays.cpp:8:8:8:13 | access to array | semmle.label | access to array |
@@ -1398,12 +1147,10 @@ nodes
| arrays.cpp:37:8:37:22 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:37:10:37:15 | nested indirection [arr, data] | semmle.label | nested indirection [arr, data] |
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
-| arrays.cpp:37:24:37:27 | data indirection | semmle.label | data indirection |
| arrays.cpp:38:8:38:8 | o indirection [nested, arr, data] | semmle.label | o indirection [nested, arr, data] |
| arrays.cpp:38:8:38:22 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:38:10:38:15 | nested indirection [arr, data] | semmle.label | nested indirection [arr, data] |
| arrays.cpp:38:24:38:27 | data | semmle.label | data |
-| arrays.cpp:38:24:38:27 | data indirection | semmle.label | data indirection |
| arrays.cpp:42:3:42:40 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | semmle.label | o indirection [post update] [indirect indirection, arr, data] |
| arrays.cpp:42:15:42:17 | indirect indirection [post update] [arr, data] | semmle.label | indirect indirection [post update] [arr, data] |
@@ -1412,15 +1159,11 @@ nodes
| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | semmle.label | o indirection [indirect indirection, arr, data] |
| arrays.cpp:43:8:43:25 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] |
-| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] |
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
-| arrays.cpp:43:27:43:30 | data indirection | semmle.label | data indirection |
| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | semmle.label | o indirection [indirect indirection, arr, data] |
| arrays.cpp:44:8:44:25 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] |
-| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] |
| arrays.cpp:44:27:44:30 | data | semmle.label | data |
-| arrays.cpp:44:27:44:30 | data indirection | semmle.label | data indirection |
| arrays.cpp:48:3:48:40 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | semmle.label | o indirection [post update] [indirect indirection, ptr indirection, data] |
| arrays.cpp:48:15:48:17 | indirect indirection [post update] [ptr indirection, data] | semmle.label | indirect indirection [post update] [ptr indirection, data] |
@@ -1429,17 +1172,13 @@ nodes
| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | semmle.label | o indirection [indirect indirection, ptr indirection, data] |
| arrays.cpp:49:8:49:25 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] |
-| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] |
| arrays.cpp:49:20:49:22 | ptr indirection [data] | semmle.label | ptr indirection [data] |
| arrays.cpp:49:27:49:30 | data | semmle.label | data |
-| arrays.cpp:49:27:49:30 | data indirection | semmle.label | data indirection |
| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | semmle.label | o indirection [indirect indirection, ptr indirection, data] |
| arrays.cpp:50:8:50:25 | access to array indirection [data] | semmle.label | access to array indirection [data] |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] |
-| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:20:50:22 | ptr indirection [data] | semmle.label | ptr indirection [data] |
| arrays.cpp:50:27:50:30 | data | semmle.label | data |
-| arrays.cpp:50:27:50:30 | data indirection | semmle.label | data indirection |
| by_reference.cpp:11:48:11:52 | value | semmle.label | value |
| by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:12:8:12:8 | s indirection [post update] [a] | semmle.label | s indirection [post update] [a] |
@@ -1456,12 +1195,10 @@ nodes
| by_reference.cpp:31:46:31:46 | s indirection [a] | semmle.label | s indirection [a] |
| by_reference.cpp:32:12:32:12 | s indirection [a] | semmle.label | s indirection [a] |
| by_reference.cpp:32:15:32:15 | a | semmle.label | a |
-| by_reference.cpp:32:15:32:15 | a indirection | semmle.label | a indirection |
| by_reference.cpp:35:9:35:19 | getDirectly indirection | semmle.label | getDirectly indirection |
| by_reference.cpp:35:9:35:19 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:36:12:36:15 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:36:18:36:18 | a | semmle.label | a |
-| by_reference.cpp:36:18:36:18 | a indirection | semmle.label | a indirection |
| by_reference.cpp:39:9:39:21 | getIndirectly indirection | semmle.label | getIndirectly indirection |
| by_reference.cpp:39:9:39:21 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | semmle.label | this indirection [a] |
@@ -1511,27 +1248,19 @@ nodes
| by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | semmle.label | outer indirection [inner_nested, a] |
| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] |
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
-| by_reference.cpp:110:27:110:27 | a indirection | semmle.label | a indirection |
| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | semmle.label | outer indirection [inner_ptr indirection, a] |
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
-| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
| by_reference.cpp:111:25:111:25 | a | semmle.label | a |
-| by_reference.cpp:111:25:111:25 | a indirection | semmle.label | a indirection |
| by_reference.cpp:112:8:112:12 | outer indirection [a] | semmle.label | outer indirection [a] |
| by_reference.cpp:112:14:112:14 | a | semmle.label | a |
-| by_reference.cpp:112:14:112:14 | a indirection | semmle.label | a indirection |
| by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | semmle.label | pouter indirection [inner_nested, a] |
| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] |
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
-| by_reference.cpp:114:29:114:29 | a indirection | semmle.label | a indirection |
| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | semmle.label | pouter indirection [inner_ptr indirection, a] |
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
-| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
| by_reference.cpp:115:27:115:27 | a | semmle.label | a |
-| by_reference.cpp:115:27:115:27 | a indirection | semmle.label | a indirection |
| by_reference.cpp:116:8:116:13 | pouter indirection [a] | semmle.label | pouter indirection [a] |
| by_reference.cpp:116:16:116:16 | a | semmle.label | a |
-| by_reference.cpp:116:16:116:16 | a indirection | semmle.label | a indirection |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
| by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] | semmle.label | outer indirection [post update] [inner_nested, a] |
| by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
@@ -1547,35 +1276,25 @@ nodes
| by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | semmle.label | outer indirection [inner_nested, a] |
| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] |
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
-| by_reference.cpp:130:27:130:27 | a indirection | semmle.label | a indirection |
| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | semmle.label | outer indirection [inner_ptr indirection, a] |
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
-| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
| by_reference.cpp:131:25:131:25 | a | semmle.label | a |
-| by_reference.cpp:131:25:131:25 | a indirection | semmle.label | a indirection |
| by_reference.cpp:132:8:132:12 | outer indirection [a] | semmle.label | outer indirection [a] |
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
-| by_reference.cpp:132:14:132:14 | a indirection | semmle.label | a indirection |
| by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | semmle.label | pouter indirection [inner_nested, a] |
| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] |
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
-| by_reference.cpp:134:29:134:29 | a indirection | semmle.label | a indirection |
| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | semmle.label | pouter indirection [inner_ptr indirection, a] |
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
-| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] |
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
-| by_reference.cpp:135:27:135:27 | a indirection | semmle.label | a indirection |
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | semmle.label | pouter indirection [a] |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
-| by_reference.cpp:136:16:136:16 | a indirection | semmle.label | a indirection |
| clearning.cpp:32:3:32:25 | ... = ... | semmle.label | ... = ... |
| clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] |
| clearning.cpp:32:10:32:19 | call to user_input | semmle.label | call to user_input |
| clearning.cpp:33:5:33:5 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
| clearning.cpp:34:8:34:11 | * ... | semmle.label | * ... |
| clearning.cpp:34:9:34:9 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
-| clearning.cpp:34:11:34:11 | x indirection | semmle.label | x indirection |
-| clearning.cpp:34:11:34:11 | x indirection | semmle.label | x indirection |
| clearning.cpp:53:3:53:25 | ... = ... | semmle.label | ... = ... |
| clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] |
| clearning.cpp:53:10:53:19 | call to user_input | semmle.label | call to user_input |
@@ -1602,8 +1321,6 @@ nodes
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:76:7:76:12 | * ... | semmle.label | * ... |
| clearning.cpp:76:8:76:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:76:10:76:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:76:10:76:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:81:20:81:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:83:5:83:21 | ... = ... indirection | semmle.label | ... = ... indirection |
@@ -1613,8 +1330,6 @@ nodes
| clearning.cpp:83:15:83:17 | val indirection | semmle.label | val indirection |
| clearning.cpp:84:7:84:12 | * ... | semmle.label | * ... |
| clearning.cpp:84:8:84:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:84:10:84:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:84:10:84:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:89:20:89:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:90:3:90:3 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
@@ -1624,8 +1339,6 @@ nodes
| clearning.cpp:90:5:90:7 | val indirection | semmle.label | val indirection |
| clearning.cpp:91:7:91:12 | * ... | semmle.label | * ... |
| clearning.cpp:91:8:91:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:91:10:91:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:91:10:91:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:96:20:96:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:97:2:97:18 | ... = ... indirection | semmle.label | ... = ... indirection |
@@ -1635,8 +1348,6 @@ nodes
| clearning.cpp:97:12:97:14 | val indirection | semmle.label | val indirection |
| clearning.cpp:98:7:98:12 | * ... | semmle.label | * ... |
| clearning.cpp:98:8:98:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:98:10:98:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:98:10:98:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:103:20:103:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:104:2:104:2 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
@@ -1646,8 +1357,6 @@ nodes
| clearning.cpp:104:4:104:6 | val indirection | semmle.label | val indirection |
| clearning.cpp:105:7:105:12 | * ... | semmle.label | * ... |
| clearning.cpp:105:8:105:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:105:10:105:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:105:10:105:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:110:20:110:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:111:2:111:8 | ++ ... indirection | semmle.label | ++ ... indirection |
@@ -1657,8 +1366,6 @@ nodes
| clearning.cpp:111:6:111:8 | val indirection | semmle.label | val indirection |
| clearning.cpp:112:7:112:12 | * ... | semmle.label | * ... |
| clearning.cpp:112:8:112:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:112:10:112:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:112:10:112:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:117:20:117:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:118:2:118:2 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
@@ -1668,23 +1375,18 @@ nodes
| clearning.cpp:118:4:118:6 | val indirection | semmle.label | val indirection |
| clearning.cpp:119:7:119:12 | * ... | semmle.label | * ... |
| clearning.cpp:119:8:119:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] |
-| clearning.cpp:119:10:119:12 | val indirection | semmle.label | val indirection |
-| clearning.cpp:119:10:119:12 | val indirection | semmle.label | val indirection |
| clearning.cpp:151:3:151:22 | ... = ... | semmle.label | ... = ... |
| clearning.cpp:151:5:151:7 | s indirection [post update] [val] | semmle.label | s indirection [post update] [val] |
| clearning.cpp:151:11:151:20 | call to user_input | semmle.label | call to user_input |
| clearning.cpp:152:8:152:8 | s indirection [val] | semmle.label | s indirection [val] |
| clearning.cpp:152:10:152:12 | val | semmle.label | val |
-| clearning.cpp:152:10:152:12 | val indirection | semmle.label | val indirection |
| complex.cpp:9:7:9:7 | a indirection | semmle.label | a indirection |
| complex.cpp:9:7:9:7 | this indirection [a_] | semmle.label | this indirection [a_] |
| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ |
-| complex.cpp:9:20:9:21 | a_ indirection | semmle.label | a_ indirection |
| complex.cpp:9:20:9:21 | this indirection [a_] | semmle.label | this indirection [a_] |
| complex.cpp:10:7:10:7 | b indirection | semmle.label | b indirection |
| complex.cpp:10:7:10:7 | this indirection [b_] | semmle.label | this indirection [b_] |
| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ |
-| complex.cpp:10:20:10:21 | b_ indirection | semmle.label | b_ indirection |
| complex.cpp:10:20:10:21 | this indirection [b_] | semmle.label | this indirection [b_] |
| complex.cpp:11:17:11:17 | a | semmle.label | a |
| complex.cpp:11:22:11:23 | this indirection [post update] [a_] | semmle.label | this indirection [post update] [a_] |
@@ -1735,51 +1437,40 @@ nodes
| conflated.cpp:10:11:10:20 | call to user_input | semmle.label | call to user_input |
| conflated.cpp:11:8:11:12 | * ... | semmle.label | * ... |
| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | semmle.label | ra indirection [p indirection] |
-| conflated.cpp:11:12:11:12 | p indirection | semmle.label | p indirection |
-| conflated.cpp:11:12:11:12 | p indirection | semmle.label | p indirection |
| conflated.cpp:19:19:19:21 | argument_source output argument | semmle.label | argument_source output argument |
| conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection |
| conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection |
-| conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection |
| conflated.cpp:29:3:29:22 | ... = ... | semmle.label | ... = ... |
| conflated.cpp:29:7:29:7 | pa indirection [post update] [x] | semmle.label | pa indirection [post update] [x] |
| conflated.cpp:29:11:29:20 | call to user_input | semmle.label | call to user_input |
| conflated.cpp:30:8:30:9 | pa indirection [x] | semmle.label | pa indirection [x] |
| conflated.cpp:30:12:30:12 | x | semmle.label | x |
-| conflated.cpp:30:12:30:12 | x indirection | semmle.label | x indirection |
| conflated.cpp:36:3:36:22 | ... = ... | semmle.label | ... = ... |
| conflated.cpp:36:7:36:7 | pa indirection [post update] [x] | semmle.label | pa indirection [post update] [x] |
| conflated.cpp:36:11:36:20 | call to user_input | semmle.label | call to user_input |
| conflated.cpp:37:8:37:9 | pa indirection [x] | semmle.label | pa indirection [x] |
| conflated.cpp:37:12:37:12 | x | semmle.label | x |
-| conflated.cpp:37:12:37:12 | x indirection | semmle.label | x indirection |
| conflated.cpp:54:3:54:28 | ... = ... | semmle.label | ... = ... |
| conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] | semmle.label | ll indirection [post update] [next indirection, y] |
| conflated.cpp:54:13:54:13 | next indirection [post update] [y] | semmle.label | next indirection [post update] [y] |
| conflated.cpp:54:17:54:26 | call to user_input | semmle.label | call to user_input |
| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | semmle.label | ll indirection [next indirection, y] |
| conflated.cpp:55:12:55:15 | next indirection [y] | semmle.label | next indirection [y] |
-| conflated.cpp:55:12:55:15 | next indirection [y] | semmle.label | next indirection [y] |
| conflated.cpp:55:18:55:18 | y | semmle.label | y |
-| conflated.cpp:55:18:55:18 | y indirection | semmle.label | y indirection |
| conflated.cpp:60:3:60:28 | ... = ... | semmle.label | ... = ... |
| conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | semmle.label | ll indirection [post update] [next indirection, y] |
| conflated.cpp:60:13:60:13 | next indirection [post update] [y] | semmle.label | next indirection [post update] [y] |
| conflated.cpp:60:17:60:26 | call to user_input | semmle.label | call to user_input |
| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | semmle.label | ll indirection [next indirection, y] |
| conflated.cpp:61:12:61:15 | next indirection [y] | semmle.label | next indirection [y] |
-| conflated.cpp:61:12:61:15 | next indirection [y] | semmle.label | next indirection [y] |
| conflated.cpp:61:18:61:18 | y | semmle.label | y |
-| conflated.cpp:61:18:61:18 | y indirection | semmle.label | y indirection |
| constructors.cpp:18:9:18:9 | a indirection | semmle.label | a indirection |
| constructors.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] |
| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ |
-| constructors.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection |
| constructors.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] |
| constructors.cpp:19:9:19:9 | b indirection | semmle.label | b indirection |
| constructors.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] |
| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ |
-| constructors.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection |
| constructors.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] |
| constructors.cpp:23:13:23:13 | a | semmle.label | a |
| constructors.cpp:23:20:23:20 | b | semmle.label | b |
@@ -1820,51 +1511,39 @@ nodes
| qualifiers.cpp:22:27:22:36 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:23:16:23:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:23:23:23:23 | a | semmle.label | a |
-| qualifiers.cpp:23:23:23:23 | a indirection | semmle.label | a indirection |
| qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] |
| qualifiers.cpp:27:11:27:18 | setA output argument [a] | semmle.label | setA output argument [a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:28:16:28:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:28:23:28:23 | a | semmle.label | a |
-| qualifiers.cpp:28:23:28:23 | a indirection | semmle.label | a indirection |
| qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] |
| qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | semmle.label | pointerSetA output argument [a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:33:16:33:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:33:23:33:23 | a | semmle.label | a |
-| qualifiers.cpp:33:23:33:23 | a indirection | semmle.label | a indirection |
| qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | semmle.label | referenceSetA output argument [a] |
| qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:38:16:38:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:38:23:38:23 | a | semmle.label | a |
-| qualifiers.cpp:38:23:38:23 | a indirection | semmle.label | a indirection |
| qualifiers.cpp:42:5:42:40 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] |
| qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | semmle.label | * ... indirection [post update] [a] |
| qualifiers.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:43:16:43:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:43:23:43:23 | a | semmle.label | a |
-| qualifiers.cpp:43:23:43:23 | a indirection | semmle.label | a indirection |
| qualifiers.cpp:47:5:47:42 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] |
| qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | semmle.label | call to getInner indirection [post update] [a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] |
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | semmle.label | inner indirection [a] |
-| qualifiers.cpp:48:16:48:20 | inner indirection [a] | semmle.label | inner indirection [a] |
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
-| qualifiers.cpp:48:23:48:23 | a indirection | semmle.label | a indirection |
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
| realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | semmle.label | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] |
| realistic.cpp:53:20:53:22 | access to array indirection [post update] [baz indirection, userInput, bufferLen] | semmle.label | access to array indirection [post update] [baz indirection, userInput, bufferLen] |
@@ -1876,19 +1555,15 @@ nodes
| realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | semmle.label | foo indirection [bar, baz indirection, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | semmle.label | access to array indirection [baz indirection, userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | semmle.label | baz indirection [userInput, bufferLen] |
-| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | semmle.label | baz indirection [userInput, bufferLen] |
| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | semmle.label | userInput indirection [bufferLen] |
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
-| realistic.cpp:61:47:61:55 | bufferLen indirection | semmle.label | bufferLen indirection |
| simple.cpp:18:9:18:9 | a indirection | semmle.label | a indirection |
| simple.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] |
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
-| simple.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection |
| simple.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] |
| simple.cpp:19:9:19:9 | b indirection | semmle.label | b indirection |
| simple.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] |
| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ |
-| simple.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection |
| simple.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] |
| simple.cpp:20:19:20:19 | a | semmle.label | a |
| simple.cpp:20:24:20:25 | this indirection [post update] [a_] | semmle.label | this indirection [post update] [a_] |
@@ -1919,13 +1594,11 @@ nodes
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:67:10:67:11 | a2 indirection [i] | semmle.label | a2 indirection [i] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
-| simple.cpp:67:13:67:13 | i indirection | semmle.label | i indirection |
| simple.cpp:78:9:78:15 | getf2f1 indirection | semmle.label | getf2f1 indirection |
| simple.cpp:78:9:78:15 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | semmle.label | f2 indirection [f1] |
| simple.cpp:79:16:79:17 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] |
| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 |
-| simple.cpp:79:19:79:20 | f1 indirection | semmle.label | f1 indirection |
| simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | semmle.label | this indirection [post update] [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... |
| simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] | semmle.label | f2 indirection [post update] [f1] |
@@ -1937,18 +1610,15 @@ nodes
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:94:10:94:11 | a2 indirection [i] | semmle.label | a2 indirection [i] |
| simple.cpp:94:13:94:13 | i | semmle.label | i |
-| simple.cpp:94:13:94:13 | i indirection | semmle.label | i indirection |
| struct_init.c:14:24:14:25 | ab indirection [a] | semmle.label | ab indirection [a] |
| struct_init.c:15:8:15:9 | ab indirection [a] | semmle.label | ab indirection [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a |
-| struct_init.c:15:12:15:12 | a indirection | semmle.label | a indirection |
| struct_init.c:20:13:20:14 | definition of ab indirection [a] | semmle.label | definition of ab indirection [a] |
| struct_init.c:20:17:20:36 | definition of ab indirection [post update] [a] | semmle.label | definition of ab indirection [post update] [a] |
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
| struct_init.c:22:8:22:9 | ab indirection [a] | semmle.label | ab indirection [a] |
| struct_init.c:22:11:22:11 | a | semmle.label | a |
-| struct_init.c:22:11:22:11 | a indirection | semmle.label | a indirection |
| struct_init.c:24:10:24:12 | & ... indirection [a] | semmle.label | & ... indirection [a] |
| struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | semmle.label | definition of outer indirection [nestedAB, a] |
| struct_init.c:26:23:29:3 | definition of outer indirection [post update] [nestedAB, a] | semmle.label | definition of outer indirection [post update] [nestedAB, a] |
@@ -1961,12 +1631,9 @@ nodes
| struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | semmle.label | outer indirection [nestedAB, a] |
| struct_init.c:31:14:31:21 | nestedAB indirection [a] | semmle.label | nestedAB indirection [a] |
| struct_init.c:31:23:31:23 | a | semmle.label | a |
-| struct_init.c:31:23:31:23 | a indirection | semmle.label | a indirection |
| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | semmle.label | outer indirection [pointerAB indirection, a] |
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] |
-| struct_init.c:33:14:33:22 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] |
| struct_init.c:33:25:33:25 | a | semmle.label | a |
-| struct_init.c:33:25:33:25 | a indirection | semmle.label | a indirection |
| struct_init.c:36:10:36:24 | & ... indirection [a] | semmle.label | & ... indirection [a] |
| struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | semmle.label | outer indirection [nestedAB, a] |
| struct_init.c:40:13:40:14 | definition of ab indirection [a] | semmle.label | definition of ab indirection [a] |
@@ -1977,7 +1644,6 @@ nodes
| struct_init.c:43:5:43:7 | & ... indirection [a] | semmle.label | & ... indirection [a] |
| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | semmle.label | outer indirection [pointerAB indirection, a] |
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] |
-| struct_init.c:46:16:46:24 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] |
subpaths
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | A.cpp:25:13:25:13 | this indirection [post update] [c] | A.cpp:31:14:31:21 | call to B [c] |
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | A.cpp:29:15:29:18 | make indirection [c] | A.cpp:48:12:48:18 | call to make indirection [c] |
@@ -2084,7 +1750,6 @@ subpaths
| D.cpp:64:25:64:28 | elem | D.cpp:56:15:56:24 | new | D.cpp:64:25:64:28 | elem | elem flows from $@ | D.cpp:56:15:56:24 | new | new |
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:30:21:30:33 | argument_source output argument | E.cpp:21:18:21:23 | buffer indirection | buffer indirection flows from $@ | E.cpp:30:21:30:33 | argument_source output argument | argument_source output argument |
| E.cpp:31:10:31:12 | raw indirection | E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | raw indirection flows from $@ | E.cpp:28:21:28:23 | argument_source output argument | argument_source output argument |
-| E.cpp:31:10:31:12 | raw indirection | E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | raw indirection flows from $@ | E.cpp:28:21:28:23 | argument_source output argument | argument_source output argument |
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:29:21:29:29 | argument_source output argument | E.cpp:32:13:32:18 | buffer indirection | buffer indirection flows from $@ | E.cpp:29:21:29:29 | argument_source output argument | argument_source output argument |
| aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input | call to user_input |
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
@@ -2147,7 +1812,6 @@ subpaths
| conflated.cpp:11:8:11:12 | * ... | conflated.cpp:10:11:10:20 | call to user_input | conflated.cpp:11:8:11:12 | * ... | * ... flows from $@ | conflated.cpp:10:11:10:20 | call to user_input | call to user_input |
| conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument |
| conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument |
-| conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument |
| conflated.cpp:30:12:30:12 | x | conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:30:12:30:12 | x | x flows from $@ | conflated.cpp:29:11:29:20 | call to user_input | call to user_input |
| conflated.cpp:37:12:37:12 | x | conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:37:12:37:12 | x | x flows from $@ | conflated.cpp:36:11:36:20 | call to user_input | call to user_input |
| conflated.cpp:55:18:55:18 | y | conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:55:18:55:18 | y | y flows from $@ | conflated.cpp:54:17:54:26 | call to user_input | call to user_input |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 97e2352000a..0065ae75d21 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -3,5 +3,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint
WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:61,22-30)
WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33)
WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33)
-failures
testFailures
+failures
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index 02e9045bcdb..9c261125c2f 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -15553,6 +15553,193 @@ ir.cpp:
# 2030| Type = [IntType] int
# 2030| ValueCategory = prvalue
# 2031| getStmt(2): [ReturnStmt] return ...
+# 2033| [TopLevelFunction] void NewDeleteMem()
+# 2033| :
+# 2033| getEntryPoint(): [BlockStmt] { ... }
+# 2034| getStmt(0): [DeclStmt] declaration
+# 2034| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
+# 2034| Type = [IntPointerType] int *
+# 2034| getVariable().getInitializer(): [Initializer] initializer for x
+# 2034| getExpr(): [NewExpr] new
+# 2034| Type = [IntPointerType] int *
+# 2034| ValueCategory = prvalue
+# 2035| getStmt(1): [ExprStmt] ExprStmt
+# 2035| getExpr(): [AssignExpr] ... = ...
+# 2035| Type = [IntType] int
+# 2035| ValueCategory = lvalue
+# 2035| getLValue(): [PointerDereferenceExpr] * ...
+# 2035| Type = [IntType] int
+# 2035| ValueCategory = lvalue
+# 2035| getOperand(): [VariableAccess] x
+# 2035| Type = [IntPointerType] int *
+# 2035| ValueCategory = prvalue(load)
+# 2035| getRValue(): [Literal] 6
+# 2035| Type = [IntType] int
+# 2035| Value = [Literal] 6
+# 2035| ValueCategory = prvalue
+# 2036| getStmt(2): [ExprStmt] ExprStmt
+# 2036| getExpr(): [DeleteExpr] delete
+# 2036| Type = [VoidType] void
+# 2036| ValueCategory = prvalue
+# 2036| getExpr(): [VariableAccess] x
+# 2036| Type = [IntPointerType] int *
+# 2036| ValueCategory = prvalue(load)
+# 2037| getStmt(3): [ReturnStmt] return ...
+# 2039| [CopyAssignmentOperator] Base2& Base2::operator=(Base2 const&)
+# 2039| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const Base2 &
+# 2039| [Constructor] void Base2::Base2()
+# 2039| :
+# 2039| :
+# 2039| getEntryPoint(): [BlockStmt] { ... }
+# 2039| getStmt(0): [ReturnStmt] return ...
+# 2039| [CopyConstructor] void Base2::Base2(Base2 const&)
+# 2039| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const Base2 &
+# 2041| [MemberFunction] void Base2::operator delete(void*)
+# 2041| :
+# 2041| getParameter(0): [Parameter] p
+# 2041| Type = [VoidPointerType] void *
+# 2041| getEntryPoint(): [BlockStmt] { ... }
+# 2042| getStmt(0): [ReturnStmt] return ...
+# 2043| [Destructor,VirtualFunction] void Base2::~Base2()
+# 2043| :
+# 2043| getEntryPoint(): [BlockStmt] { ... }
+# 2043| getStmt(0): [ReturnStmt] return ...
+# 2043| :
+# 2046| [CopyAssignmentOperator] Derived2& Derived2::operator=(Derived2 const&)
+# 2046| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const Derived2 &
+# 2046| [Constructor] void Derived2::Derived2()
+# 2046| :
+# 2046| :
+# 2046| getInitializer(0): [ConstructorDirectInit] call to Base2
+# 2046| Type = [VoidType] void
+# 2046| ValueCategory = prvalue
+# 2046| getEntryPoint(): [BlockStmt] { ... }
+# 2046| getStmt(0): [ReturnStmt] return ...
+# 2046| [CopyConstructor] void Derived2::Derived2(Derived2 const&)
+# 2046| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const Derived2 &
+# 2049| [Destructor,VirtualFunction] void Derived2::~Derived2()
+# 2049| :
+# 2049| getEntryPoint(): [BlockStmt] { ... }
+# 2049| getStmt(0): [ReturnStmt] return ...
+# 2049| :
+# 2049| getDestruction(0): [DestructorDirectDestruction] call to ~Base2
+# 2049| Type = [VoidType] void
+# 2049| ValueCategory = prvalue
+# 2051| [MemberFunction] void Derived2::operator delete(void*)
+# 2051| :
+# 2051| getParameter(0): [Parameter] p
+# 2051| Type = [VoidPointerType] void *
+# 2051| getEntryPoint(): [BlockStmt] { ... }
+# 2052| getStmt(0): [ReturnStmt] return ...
+# 2056| [TopLevelFunction] int virtual_delete()
+# 2056| :
+# 2057| getEntryPoint(): [BlockStmt] { ... }
+# 2058| getStmt(0): [DeclStmt] declaration
+# 2058| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b1
+# 2058| Type = [PointerType] Base2 *
+# 2058| getVariable().getInitializer(): [Initializer] initializer for b1
+# 2058| getExpr(): [NewExpr] new
+# 2058| Type = [PointerType] Base2 *
+# 2058| ValueCategory = prvalue
+# 2058| getInitializer(): [ConstructorCall] call to Base2
+# 2058| Type = [VoidType] void
+# 2058| ValueCategory = prvalue
+# 2059| getStmt(1): [ExprStmt] ExprStmt
+# 2059| getExpr(): [DeleteExpr] delete
+# 2059| Type = [VoidType] void
+# 2059| ValueCategory = prvalue
+# 2059| getDeallocatorCall(): [FunctionCall] call to operator delete
+# 2059| Type = [VoidType] void
+# 2059| ValueCategory = prvalue
+# 2059| getDestructorCall(): [DestructorCall] call to ~Base2
+# 2059| Type = [VoidType] void
+# 2059| ValueCategory = prvalue
+# 2059| getQualifier(): [VariableAccess] b1
+# 2059| Type = [PointerType] Base2 *
+# 2059| ValueCategory = prvalue(load)
+# 2061| getStmt(2): [DeclStmt] declaration
+# 2061| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b2
+# 2061| Type = [PointerType] Base2 *
+# 2061| getVariable().getInitializer(): [Initializer] initializer for b2
+# 2061| getExpr(): [NewExpr] new
+# 2061| Type = [PointerType] Derived2 *
+# 2061| ValueCategory = prvalue
+# 2061| getInitializer(): [ConstructorCall] call to Derived2
+# 2061| Type = [VoidType] void
+# 2061| ValueCategory = prvalue
+# 2061| getExpr().getFullyConverted(): [CStyleCast] (Base2 *)...
+# 2061| Conversion = [BaseClassConversion] base class conversion
+# 2061| Type = [PointerType] Base2 *
+# 2061| ValueCategory = prvalue
+# 2062| getStmt(3): [ExprStmt] ExprStmt
+# 2062| getExpr(): [DeleteExpr] delete
+# 2062| Type = [VoidType] void
+# 2062| ValueCategory = prvalue
+# 2062| getDeallocatorCall(): [FunctionCall] call to operator delete
+# 2062| Type = [VoidType] void
+# 2062| ValueCategory = prvalue
+# 2062| getDestructorCall(): [DestructorCall] call to ~Base2
+# 2062| Type = [VoidType] void
+# 2062| ValueCategory = prvalue
+# 2062| getQualifier(): [VariableAccess] b2
+# 2062| Type = [PointerType] Base2 *
+# 2062| ValueCategory = prvalue(load)
+# 2064| getStmt(4): [DeclStmt] declaration
+# 2064| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
+# 2064| Type = [PointerType] Derived2 *
+# 2064| getVariable().getInitializer(): [Initializer] initializer for d
+# 2064| getExpr(): [NewExpr] new
+# 2064| Type = [PointerType] Derived2 *
+# 2064| ValueCategory = prvalue
+# 2064| getInitializer(): [ConstructorCall] call to Derived2
+# 2064| Type = [VoidType] void
+# 2064| ValueCategory = prvalue
+# 2065| getStmt(5): [ExprStmt] ExprStmt
+# 2065| getExpr(): [DeleteExpr] delete
+# 2065| Type = [VoidType] void
+# 2065| ValueCategory = prvalue
+# 2065| getDeallocatorCall(): [FunctionCall] call to operator delete
+# 2065| Type = [VoidType] void
+# 2065| ValueCategory = prvalue
+# 2065| getDestructorCall(): [DestructorCall] call to ~Derived2
+# 2065| Type = [VoidType] void
+# 2065| ValueCategory = prvalue
+# 2065| getQualifier(): [VariableAccess] d
+# 2065| Type = [PointerType] Derived2 *
+# 2065| ValueCategory = prvalue(load)
+# 2066| getStmt(6): [ReturnStmt] return ...
+# 2068| [TopLevelFunction] void test_constant_folding_use(int)
+# 2068| :
+# 2068| getParameter(0): [Parameter] (unnamed parameter 0)
+# 2068| Type = [IntType] int
+# 2070| [TopLevelFunction] void test_constant_folding()
+# 2070| :
+# 2070| getEntryPoint(): [BlockStmt] { ... }
+# 2071| getStmt(0): [DeclStmt] declaration
+# 2071| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
+# 2071| Type = [SpecifiedType] const int
+# 2071| getVariable().getInitializer(): [Initializer] initializer for x
+# 2071| getExpr(): [Literal] 116
+# 2071| Type = [IntType] int
+# 2071| Value = [Literal] 116
+# 2071| ValueCategory = prvalue
+# 2072| getStmt(1): [ExprStmt] ExprStmt
+# 2072| getExpr(): [FunctionCall] call to test_constant_folding_use
+# 2072| Type = [VoidType] void
+# 2072| ValueCategory = prvalue
+# 2072| getArgument(0): [VariableAccess] x
+# 2072| Type = [IntType] int
+# 2072| Value = [VariableAccess] 116
+# 2072| ValueCategory = prvalue(load)
+# 2073| getStmt(2): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| :
diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp
index 44f88d23166..e3de7919375 100644
--- a/cpp/ql/test/library-tests/ir/ir/ir.cpp
+++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp
@@ -2030,4 +2030,46 @@ unsigned int CommaTest(unsigned int x) {
(CommaTestHelper(x), 10);
}
+void NewDeleteMem() {
+ int* x = new int; // No constructor
+ *x = 6;
+ delete x;
+}
+
+class Base2 {
+public:
+ void operator delete(void* p) {
+ }
+ virtual ~Base2() {};
+};
+
+class Derived2 : public Base2 {
+ int i;
+public:
+ ~Derived2() {};
+
+ void operator delete(void* p) {
+ }
+};
+
+// Delete is kind-of virtual in these cases
+int virtual_delete()
+{
+ Base2* b1 = new Base2{};
+ delete b1;
+
+ Base2* b2 = new Derived2{};
+ delete b2;
+
+ Derived2* d = new Derived2{};
+ delete d;
+}
+
+void test_constant_folding_use(int);
+
+void test_constant_folding() {
+ const int x = 116;
+ test_constant_folding_use(x);
+}
+
// semmle-extractor-options: -std=c++17 --clang
diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
index bfe31bbefe7..e8a8d7e06b7 100644
--- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
+++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
@@ -4887,10 +4887,60 @@
| ir.cpp:1011:12:1011:12 | Unary | r1011_3 |
| ir.cpp:1015:6:1015:19 | ChiPartial | partial:m1015_3 |
| ir.cpp:1015:6:1015:19 | ChiTotal | total:m1015_2 |
-| ir.cpp:1015:6:1015:19 | SideEffect | m1015_3 |
+| ir.cpp:1015:6:1015:19 | SideEffect | ~m1020_5 |
+| ir.cpp:1016:3:1016:35 | CallTarget | func:r1016_1 |
+| ir.cpp:1016:3:1016:35 | ChiPartial | partial:m1016_4 |
+| ir.cpp:1016:3:1016:35 | ChiTotal | total:m1015_4 |
+| ir.cpp:1016:3:1016:35 | SideEffect | ~m1015_4 |
+| ir.cpp:1016:10:1016:35 | Arg(0) | 0:r1016_2 |
+| ir.cpp:1017:3:1017:38 | CallTarget | func:r1017_1 |
+| ir.cpp:1017:3:1017:38 | ChiPartial | partial:m1017_4 |
+| ir.cpp:1017:3:1017:38 | ChiTotal | total:m1016_5 |
+| ir.cpp:1017:3:1017:38 | SideEffect | ~m1016_5 |
+| ir.cpp:1017:10:1017:38 | Arg(0) | 0:r1017_2 |
+| ir.cpp:1018:3:1018:44 | CallTarget | func:r1018_1 |
+| ir.cpp:1018:3:1018:44 | ChiPartial | partial:m1018_4 |
+| ir.cpp:1018:3:1018:44 | ChiTotal | total:m1017_5 |
+| ir.cpp:1018:3:1018:44 | SideEffect | ~m1017_5 |
+| ir.cpp:1018:10:1018:44 | Arg(0) | 0:r1018_2 |
+| ir.cpp:1019:3:1019:43 | CallTarget | func:r1019_1 |
+| ir.cpp:1019:3:1019:43 | ChiPartial | partial:m1019_4 |
+| ir.cpp:1019:3:1019:43 | ChiTotal | total:m1018_5 |
+| ir.cpp:1019:3:1019:43 | SideEffect | ~m1018_5 |
+| ir.cpp:1019:10:1019:43 | Arg(0) | 0:r1019_2 |
+| ir.cpp:1020:3:1020:47 | CallTarget | func:r1020_1 |
+| ir.cpp:1020:3:1020:47 | ChiPartial | partial:m1020_4 |
+| ir.cpp:1020:3:1020:47 | ChiTotal | total:m1019_5 |
+| ir.cpp:1020:3:1020:47 | SideEffect | ~m1019_5 |
+| ir.cpp:1020:10:1020:47 | Arg(0) | 0:r1020_2 |
| ir.cpp:1024:6:1024:24 | ChiPartial | partial:m1024_3 |
| ir.cpp:1024:6:1024:24 | ChiTotal | total:m1024_2 |
-| ir.cpp:1024:6:1024:24 | SideEffect | m1024_3 |
+| ir.cpp:1024:6:1024:24 | SideEffect | ~m1029_5 |
+| ir.cpp:1025:3:1025:37 | CallTarget | func:r1025_1 |
+| ir.cpp:1025:3:1025:37 | ChiPartial | partial:m1025_4 |
+| ir.cpp:1025:3:1025:37 | ChiTotal | total:m1024_4 |
+| ir.cpp:1025:3:1025:37 | SideEffect | ~m1024_4 |
+| ir.cpp:1025:12:1025:37 | Arg(0) | 0:r1025_2 |
+| ir.cpp:1026:3:1026:40 | CallTarget | func:r1026_1 |
+| ir.cpp:1026:3:1026:40 | ChiPartial | partial:m1026_4 |
+| ir.cpp:1026:3:1026:40 | ChiTotal | total:m1025_5 |
+| ir.cpp:1026:3:1026:40 | SideEffect | ~m1025_5 |
+| ir.cpp:1026:12:1026:40 | Arg(0) | 0:r1026_2 |
+| ir.cpp:1027:3:1027:46 | CallTarget | func:r1027_1 |
+| ir.cpp:1027:3:1027:46 | ChiPartial | partial:m1027_4 |
+| ir.cpp:1027:3:1027:46 | ChiTotal | total:m1026_5 |
+| ir.cpp:1027:3:1027:46 | SideEffect | ~m1026_5 |
+| ir.cpp:1027:12:1027:46 | Arg(0) | 0:r1027_2 |
+| ir.cpp:1028:3:1028:45 | CallTarget | func:r1028_1 |
+| ir.cpp:1028:3:1028:45 | ChiPartial | partial:m1028_4 |
+| ir.cpp:1028:3:1028:45 | ChiTotal | total:m1027_5 |
+| ir.cpp:1028:3:1028:45 | SideEffect | ~m1027_5 |
+| ir.cpp:1028:12:1028:45 | Arg(0) | 0:r1028_2 |
+| ir.cpp:1029:3:1029:49 | CallTarget | func:r1029_1 |
+| ir.cpp:1029:3:1029:49 | ChiPartial | partial:m1029_4 |
+| ir.cpp:1029:3:1029:49 | ChiTotal | total:m1028_5 |
+| ir.cpp:1029:3:1029:49 | SideEffect | ~m1028_5 |
+| ir.cpp:1029:12:1029:49 | Arg(0) | 0:r1029_2 |
| ir.cpp:1034:6:1034:20 | ChiPartial | partial:m1034_3 |
| ir.cpp:1034:6:1034:20 | ChiTotal | total:m1034_2 |
| ir.cpp:1034:6:1034:20 | SideEffect | m1034_3 |
@@ -9576,6 +9626,186 @@
| ir.cpp:2030:22:2030:22 | Arg(0) | 0:r2030_3 |
| ir.cpp:2030:22:2030:22 | Load | m2026_6 |
| ir.cpp:2030:26:2030:27 | Unary | r2030_7 |
+| ir.cpp:2033:6:2033:17 | ChiPartial | partial:m2033_3 |
+| ir.cpp:2033:6:2033:17 | ChiTotal | total:m2033_2 |
+| ir.cpp:2033:6:2033:17 | SideEffect | ~m2036_6 |
+| ir.cpp:2034:8:2034:8 | Address | &:r2034_1 |
+| ir.cpp:2034:12:2034:18 | Address | &:r2034_4 |
+| ir.cpp:2034:12:2034:18 | Arg(0) | 0:r2034_3 |
+| ir.cpp:2034:12:2034:18 | CallTarget | func:r2034_2 |
+| ir.cpp:2034:12:2034:18 | ChiPartial | partial:m2034_5 |
+| ir.cpp:2034:12:2034:18 | ChiTotal | total:m2033_4 |
+| ir.cpp:2034:12:2034:18 | SideEffect | ~m2033_4 |
+| ir.cpp:2034:12:2034:18 | StoreValue | r2034_8 |
+| ir.cpp:2034:12:2034:18 | Unary | r2034_4 |
+| ir.cpp:2035:3:2035:4 | Address | &:r2035_4 |
+| ir.cpp:2035:3:2035:8 | ChiPartial | partial:m2035_5 |
+| ir.cpp:2035:3:2035:8 | ChiTotal | total:m2034_7 |
+| ir.cpp:2035:4:2035:4 | Address | &:r2035_2 |
+| ir.cpp:2035:4:2035:4 | Load | m2034_9 |
+| ir.cpp:2035:4:2035:4 | Unary | r2035_3 |
+| ir.cpp:2035:8:2035:8 | StoreValue | r2035_1 |
+| ir.cpp:2036:3:2036:10 | CallTarget | func:r2036_1 |
+| ir.cpp:2036:3:2036:10 | ChiPartial | partial:m2036_5 |
+| ir.cpp:2036:3:2036:10 | ChiTotal | total:m2034_6 |
+| ir.cpp:2036:3:2036:10 | SideEffect | ~m2034_6 |
+| ir.cpp:2036:10:2036:10 | Address | &:r2036_2 |
+| ir.cpp:2036:10:2036:10 | Arg(0) | 0:r2036_3 |
+| ir.cpp:2036:10:2036:10 | Load | m2034_9 |
+| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 |
+| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 |
+| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 |
+| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 |
+| ir.cpp:2039:7:2039:7 | ChiPartial | partial:m2039_3 |
+| ir.cpp:2039:7:2039:7 | ChiTotal | total:m2039_2 |
+| ir.cpp:2039:7:2039:7 | Load | m2039_6 |
+| ir.cpp:2039:7:2039:7 | SideEffect | m2039_3 |
+| ir.cpp:2039:7:2039:7 | SideEffect | m2039_8 |
+| ir.cpp:2041:10:2041:24 | ChiPartial | partial:m2041_3 |
+| ir.cpp:2041:10:2041:24 | ChiTotal | total:m2041_2 |
+| ir.cpp:2041:10:2041:24 | SideEffect | m2041_3 |
+| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 |
+| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 |
+| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 |
+| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 |
+| ir.cpp:2041:32:2041:32 | Load | m2041_6 |
+| ir.cpp:2041:32:2041:32 | SideEffect | m2041_8 |
+| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 |
+| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 |
+| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 |
+| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 |
+| ir.cpp:2043:13:2043:18 | ChiPartial | partial:m2043_3 |
+| ir.cpp:2043:13:2043:18 | ChiTotal | total:m2043_2 |
+| ir.cpp:2043:13:2043:18 | Load | m2043_6 |
+| ir.cpp:2043:13:2043:18 | SideEffect | m2043_3 |
+| ir.cpp:2043:13:2043:18 | SideEffect | m2043_8 |
+| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 |
+| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 |
+| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 |
+| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 |
+| ir.cpp:2046:7:2046:7 | Address | &:r2046_9 |
+| ir.cpp:2046:7:2046:7 | Arg(this) | this:r2046_9 |
+| ir.cpp:2046:7:2046:7 | CallTarget | func:r2046_10 |
+| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_3 |
+| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_12 |
+| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_14 |
+| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_2 |
+| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_4 |
+| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_8 |
+| ir.cpp:2046:7:2046:7 | Load | m2046_6 |
+| ir.cpp:2046:7:2046:7 | SideEffect | m2046_15 |
+| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_4 |
+| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_13 |
+| ir.cpp:2046:7:2046:7 | Unary | m2046_6 |
+| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 |
+| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 |
+| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 |
+| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 |
+| ir.cpp:2049:5:2049:13 | ChiPartial | partial:m2049_3 |
+| ir.cpp:2049:5:2049:13 | ChiTotal | total:m2049_2 |
+| ir.cpp:2049:5:2049:13 | Load | m2049_6 |
+| ir.cpp:2049:5:2049:13 | SideEffect | m2049_8 |
+| ir.cpp:2049:5:2049:13 | SideEffect | ~m2049_14 |
+| ir.cpp:2049:5:2049:13 | Unary | m2049_6 |
+| ir.cpp:2049:18:2049:18 | Arg(this) | this:r2049_10 |
+| ir.cpp:2049:18:2049:18 | CallTarget | func:r2049_11 |
+| ir.cpp:2049:18:2049:18 | ChiPartial | partial:m2049_13 |
+| ir.cpp:2049:18:2049:18 | ChiTotal | total:m2049_4 |
+| ir.cpp:2049:18:2049:18 | SideEffect | ~m2049_4 |
+| ir.cpp:2051:10:2051:24 | ChiPartial | partial:m2051_3 |
+| ir.cpp:2051:10:2051:24 | ChiTotal | total:m2051_2 |
+| ir.cpp:2051:10:2051:24 | SideEffect | m2051_3 |
+| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 |
+| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 |
+| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 |
+| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 |
+| ir.cpp:2051:32:2051:32 | Load | m2051_6 |
+| ir.cpp:2051:32:2051:32 | SideEffect | m2051_8 |
+| ir.cpp:2056:5:2056:18 | ChiPartial | partial:m2056_3 |
+| ir.cpp:2056:5:2056:18 | ChiTotal | total:m2056_2 |
+| ir.cpp:2058:12:2058:13 | Address | &:r2058_1 |
+| ir.cpp:2058:17:2058:27 | Address | &:r2058_4 |
+| ir.cpp:2058:17:2058:27 | Address | &:r2058_8 |
+| ir.cpp:2058:17:2058:27 | Arg(0) | 0:r2058_3 |
+| ir.cpp:2058:17:2058:27 | Arg(this) | this:r2058_8 |
+| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_2 |
+| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_9 |
+| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_5 |
+| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_11 |
+| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_13 |
+| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2056_4 |
+| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_6 |
+| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_7 |
+| ir.cpp:2058:17:2058:27 | SideEffect | ~m2056_4 |
+| ir.cpp:2058:17:2058:27 | SideEffect | ~m2058_6 |
+| ir.cpp:2058:17:2058:27 | StoreValue | r2058_8 |
+| ir.cpp:2058:17:2058:27 | Unary | r2058_4 |
+| ir.cpp:2059:5:2059:13 | CallTarget | func:r2059_1 |
+| ir.cpp:2059:5:2059:13 | ChiPartial | partial:m2059_5 |
+| ir.cpp:2059:5:2059:13 | ChiTotal | total:m2058_12 |
+| ir.cpp:2059:5:2059:13 | SideEffect | ~m2058_12 |
+| ir.cpp:2059:12:2059:13 | Address | &:r2059_2 |
+| ir.cpp:2059:12:2059:13 | Arg(0) | 0:r2059_3 |
+| ir.cpp:2059:12:2059:13 | Load | m2058_15 |
+| ir.cpp:2061:12:2061:13 | Address | &:r2061_1 |
+| ir.cpp:2061:17:2061:30 | Address | &:r2061_4 |
+| ir.cpp:2061:17:2061:30 | Address | &:r2061_8 |
+| ir.cpp:2061:17:2061:30 | Arg(0) | 0:r2061_3 |
+| ir.cpp:2061:17:2061:30 | Arg(this) | this:r2061_8 |
+| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_2 |
+| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_9 |
+| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_5 |
+| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_11 |
+| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_13 |
+| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2059_6 |
+| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_6 |
+| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_7 |
+| ir.cpp:2061:17:2061:30 | SideEffect | ~m2059_6 |
+| ir.cpp:2061:17:2061:30 | SideEffect | ~m2061_6 |
+| ir.cpp:2061:17:2061:30 | StoreValue | r2061_15 |
+| ir.cpp:2061:17:2061:30 | Unary | r2061_4 |
+| ir.cpp:2061:17:2061:30 | Unary | r2061_8 |
+| ir.cpp:2062:5:2062:13 | CallTarget | func:r2062_1 |
+| ir.cpp:2062:5:2062:13 | ChiPartial | partial:m2062_5 |
+| ir.cpp:2062:5:2062:13 | ChiTotal | total:m2061_12 |
+| ir.cpp:2062:5:2062:13 | SideEffect | ~m2061_12 |
+| ir.cpp:2062:12:2062:13 | Address | &:r2062_2 |
+| ir.cpp:2062:12:2062:13 | Arg(0) | 0:r2062_3 |
+| ir.cpp:2062:12:2062:13 | Load | m2061_16 |
+| ir.cpp:2064:15:2064:15 | Address | &:r2064_1 |
+| ir.cpp:2064:19:2064:32 | Address | &:r2064_4 |
+| ir.cpp:2064:19:2064:32 | Address | &:r2064_8 |
+| ir.cpp:2064:19:2064:32 | Arg(0) | 0:r2064_3 |
+| ir.cpp:2064:19:2064:32 | Arg(this) | this:r2064_8 |
+| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_2 |
+| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_9 |
+| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_5 |
+| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_11 |
+| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_13 |
+| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2062_6 |
+| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_6 |
+| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_7 |
+| ir.cpp:2064:19:2064:32 | SideEffect | ~m2062_6 |
+| ir.cpp:2064:19:2064:32 | SideEffect | ~m2064_6 |
+| ir.cpp:2064:19:2064:32 | StoreValue | r2064_8 |
+| ir.cpp:2064:19:2064:32 | Unary | r2064_4 |
+| ir.cpp:2065:5:2065:12 | CallTarget | func:r2065_1 |
+| ir.cpp:2065:5:2065:12 | ChiPartial | partial:m2065_5 |
+| ir.cpp:2065:5:2065:12 | ChiTotal | total:m2064_12 |
+| ir.cpp:2065:5:2065:12 | SideEffect | ~m2064_12 |
+| ir.cpp:2065:12:2065:12 | Address | &:r2065_2 |
+| ir.cpp:2065:12:2065:12 | Arg(0) | 0:r2065_3 |
+| ir.cpp:2065:12:2065:12 | Load | m2064_15 |
+| ir.cpp:2070:6:2070:26 | ChiPartial | partial:m2070_3 |
+| ir.cpp:2070:6:2070:26 | ChiTotal | total:m2070_2 |
+| ir.cpp:2070:6:2070:26 | SideEffect | ~m2072_5 |
+| ir.cpp:2071:13:2071:13 | Address | &:r2071_1 |
+| ir.cpp:2071:16:2071:19 | StoreValue | r2071_2 |
+| ir.cpp:2072:3:2072:27 | CallTarget | func:r2072_1 |
+| ir.cpp:2072:3:2072:27 | ChiPartial | partial:m2072_4 |
+| ir.cpp:2072:3:2072:27 | ChiTotal | total:m2070_4 |
+| ir.cpp:2072:3:2072:27 | SideEffect | ~m2070_4 |
+| ir.cpp:2072:29:2072:29 | Arg(0) | 0:r2072_2 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
index 019199d980d..8bb7c6dde6a 100644
--- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
@@ -5663,43 +5663,63 @@ ir.cpp:
# 1015| void OperatorDelete()
# 1015| Block 0
-# 1015| v1015_1(void) = EnterFunction :
-# 1015| mu1015_2(unknown) = AliasedDefinition :
-# 1015| mu1015_3(unknown) = InitializeNonLocal :
-# 1016| r1016_1(int *) = Constant[0] :
-# 1016| v1016_2(void) = NoOp :
-# 1017| r1017_1(String *) = Constant[0] :
-# 1017| v1017_2(void) = NoOp :
-# 1018| r1018_1(SizedDealloc *) = Constant[0] :
-# 1018| v1018_2(void) = NoOp :
-# 1019| r1019_1(Overaligned *) = Constant[0] :
-# 1019| v1019_2(void) = NoOp :
-# 1020| r1020_1(PolymorphicBase *) = Constant[0] :
-# 1020| v1020_2(void) = NoOp :
-# 1021| v1021_1(void) = NoOp :
-# 1015| v1015_4(void) = ReturnVoid :
-# 1015| v1015_5(void) = AliasedUse : ~m?
-# 1015| v1015_6(void) = ExitFunction :
+# 1015| v1015_1(void) = EnterFunction :
+# 1015| mu1015_2(unknown) = AliasedDefinition :
+# 1015| mu1015_3(unknown) = InitializeNonLocal :
+# 1016| r1016_1(glval) = FunctionAddress[operator delete] :
+# 1016| r1016_2(int *) = Constant[0] :
+# 1016| v1016_3(void) = Call[operator delete] : func:r1016_1, 0:r1016_2
+# 1016| mu1016_4(unknown) = ^CallSideEffect : ~m?
+# 1017| r1017_1(glval) = FunctionAddress[operator delete] :
+# 1017| r1017_2(String *) = Constant[0] :
+# 1017| v1017_3(void) = Call[operator delete] : func:r1017_1, 0:r1017_2
+# 1017| mu1017_4(unknown) = ^CallSideEffect : ~m?
+# 1018| r1018_1(glval) = FunctionAddress[operator delete] :
+# 1018| r1018_2(SizedDealloc *) = Constant[0] :
+# 1018| v1018_3(void) = Call[operator delete] : func:r1018_1, 0:r1018_2
+# 1018| mu1018_4(unknown) = ^CallSideEffect : ~m?
+# 1019| r1019_1(glval) = FunctionAddress[operator delete] :
+# 1019| r1019_2(Overaligned *) = Constant[0] :
+# 1019| v1019_3(void) = Call[operator delete] : func:r1019_1, 0:r1019_2
+# 1019| mu1019_4(unknown) = ^CallSideEffect : ~m?
+# 1020| r1020_1(glval) = VirtualDeleteFunctionAddress :
+# 1020| r1020_2(PolymorphicBase *) = Constant[0] :
+# 1020| v1020_3(void) = Call[?] : func:r1020_1, 0:r1020_2
+# 1020| mu1020_4(unknown) = ^CallSideEffect : ~m?
+# 1021| v1021_1(void) = NoOp :
+# 1015| v1015_4(void) = ReturnVoid :
+# 1015| v1015_5(void) = AliasedUse : ~m?
+# 1015| v1015_6(void) = ExitFunction :
# 1024| void OperatorDeleteArray()
# 1024| Block 0
-# 1024| v1024_1(void) = EnterFunction :
-# 1024| mu1024_2(unknown) = AliasedDefinition :
-# 1024| mu1024_3(unknown) = InitializeNonLocal :
-# 1025| r1025_1(int *) = Constant[0] :
-# 1025| v1025_2(void) = NoOp :
-# 1026| r1026_1(String *) = Constant[0] :
-# 1026| v1026_2(void) = NoOp :
-# 1027| r1027_1(SizedDealloc *) = Constant[0] :
-# 1027| v1027_2(void) = NoOp :
-# 1028| r1028_1(Overaligned *) = Constant[0] :
-# 1028| v1028_2(void) = NoOp :
-# 1029| r1029_1(PolymorphicBase *) = Constant[0] :
-# 1029| v1029_2(void) = NoOp :
-# 1030| v1030_1(void) = NoOp :
-# 1024| v1024_4(void) = ReturnVoid :
-# 1024| v1024_5(void) = AliasedUse : ~m?
-# 1024| v1024_6(void) = ExitFunction :
+# 1024| v1024_1(void) = EnterFunction :
+# 1024| mu1024_2(unknown) = AliasedDefinition :
+# 1024| mu1024_3(unknown) = InitializeNonLocal :
+# 1025| r1025_1(glval) = FunctionAddress[operator delete[]] :
+# 1025| r1025_2(int *) = Constant[0] :
+# 1025| v1025_3(void) = Call[operator delete[]] : func:r1025_1, 0:r1025_2
+# 1025| mu1025_4(unknown) = ^CallSideEffect : ~m?
+# 1026| r1026_1(glval) = FunctionAddress[operator delete[]] :
+# 1026| r1026_2(String *) = Constant[0] :
+# 1026| v1026_3(void) = Call[operator delete[]] : func:r1026_1, 0:r1026_2
+# 1026| mu1026_4(unknown) = ^CallSideEffect : ~m?
+# 1027| r1027_1(glval) = FunctionAddress[operator delete[]] :
+# 1027| r1027_2(SizedDealloc *) = Constant[0] :
+# 1027| v1027_3(void) = Call[operator delete[]] : func:r1027_1, 0:r1027_2
+# 1027| mu1027_4(unknown) = ^CallSideEffect : ~m?
+# 1028| r1028_1(glval) = FunctionAddress[operator delete[]] :
+# 1028| r1028_2(Overaligned *) = Constant[0] :
+# 1028| v1028_3(void) = Call[operator delete[]] : func:r1028_1, 0:r1028_2
+# 1028| mu1028_4(unknown) = ^CallSideEffect : ~m?
+# 1029| r1029_1(glval) = FunctionAddress[operator delete[]] :
+# 1029| r1029_2(PolymorphicBase *) = Constant[0] :
+# 1029| v1029_3(void) = Call[operator delete[]] : func:r1029_1, 0:r1029_2
+# 1029| mu1029_4(unknown) = ^CallSideEffect : ~m?
+# 1030| v1030_1(void) = NoOp :
+# 1024| v1024_4(void) = ReturnVoid :
+# 1024| v1024_5(void) = AliasedUse : ~m?
+# 1024| v1024_6(void) = ExitFunction :
# 1034| void EmptyStructInit()
# 1034| Block 0
@@ -11091,6 +11111,215 @@ ir.cpp:
# 2028| mu2028_13(unsigned int) = Store[#temp2028:7] : &:r2028_12, r2030_8
#-----| Goto -> Block 2
+# 2033| void NewDeleteMem()
+# 2033| Block 0
+# 2033| v2033_1(void) = EnterFunction :
+# 2033| mu2033_2(unknown) = AliasedDefinition :
+# 2033| mu2033_3(unknown) = InitializeNonLocal :
+# 2034| r2034_1(glval) = VariableAddress[x] :
+# 2034| r2034_2(glval) = FunctionAddress[operator new] :
+# 2034| r2034_3(unsigned long) = Constant[4] :
+# 2034| r2034_4(void *) = Call[operator new] : func:r2034_2, 0:r2034_3
+# 2034| mu2034_5(unknown) = ^CallSideEffect : ~m?
+# 2034| mu2034_6(unknown) = ^InitializeDynamicAllocation : &:r2034_4
+# 2034| r2034_7(int *) = Convert : r2034_4
+# 2034| mu2034_8(int *) = Store[x] : &:r2034_1, r2034_7
+# 2035| r2035_1(int) = Constant[6] :
+# 2035| r2035_2(glval) = VariableAddress[x] :
+# 2035| r2035_3(int *) = Load[x] : &:r2035_2, ~m?
+# 2035| r2035_4(glval) = CopyValue : r2035_3
+# 2035| mu2035_5(int) = Store[?] : &:r2035_4, r2035_1
+# 2036| r2036_1(glval) = FunctionAddress[operator delete] :
+# 2036| r2036_2(glval) = VariableAddress[x] :
+# 2036| r2036_3(int *) = Load[x] : &:r2036_2, ~m?
+# 2036| v2036_4(void) = Call[operator delete] : func:r2036_1, 0:r2036_3
+# 2036| mu2036_5(unknown) = ^CallSideEffect : ~m?
+# 2037| v2037_1(void) = NoOp :
+# 2033| v2033_4(void) = ReturnVoid :
+# 2033| v2033_5(void) = AliasedUse : ~m?
+# 2033| v2033_6(void) = ExitFunction :
+
+# 2039| void Base2::Base2()
+# 2039| Block 0
+# 2039| v2039_1(void) = EnterFunction :
+# 2039| mu2039_2(unknown) = AliasedDefinition :
+# 2039| mu2039_3(unknown) = InitializeNonLocal :
+# 2039| r2039_4(glval) = VariableAddress[#this] :
+# 2039| mu2039_5(glval) = InitializeParameter[#this] : &:r2039_4
+# 2039| r2039_6(glval) = Load[#this] : &:r2039_4, ~m?
+# 2039| mu2039_7(Base2) = InitializeIndirection[#this] : &:r2039_6
+# 2039| v2039_8(void) = NoOp :
+# 2039| v2039_9(void) = ReturnIndirection[#this] : &:r2039_6, ~m?
+# 2039| v2039_10(void) = ReturnVoid :
+# 2039| v2039_11(void) = AliasedUse : ~m?
+# 2039| v2039_12(void) = ExitFunction :
+
+# 2041| void Base2::operator delete(void*)
+# 2041| Block 0
+# 2041| v2041_1(void) = EnterFunction :
+# 2041| mu2041_2(unknown) = AliasedDefinition :
+# 2041| mu2041_3(unknown) = InitializeNonLocal :
+# 2041| r2041_4(glval) = VariableAddress[p] :
+# 2041| mu2041_5(void *) = InitializeParameter[p] : &:r2041_4
+# 2041| r2041_6(void *) = Load[p] : &:r2041_4, ~m?
+# 2041| mu2041_7(unknown) = InitializeIndirection[p] : &:r2041_6
+# 2042| v2042_1(void) = NoOp :
+# 2041| v2041_8(void) = ReturnIndirection[p] : &:r2041_6, ~m?
+# 2041| v2041_9(void) = ReturnVoid :
+# 2041| v2041_10(void) = AliasedUse : ~m?
+# 2041| v2041_11(void) = ExitFunction :
+
+# 2043| void Base2::~Base2()
+# 2043| Block 0
+# 2043| v2043_1(void) = EnterFunction :
+# 2043| mu2043_2(unknown) = AliasedDefinition :
+# 2043| mu2043_3(unknown) = InitializeNonLocal :
+# 2043| r2043_4(glval) = VariableAddress[#this] :
+# 2043| mu2043_5(glval) = InitializeParameter[#this] : &:r2043_4
+# 2043| r2043_6(glval) = Load[#this] : &:r2043_4, ~m?
+# 2043| mu2043_7(Base2) = InitializeIndirection[#this] : &:r2043_6
+# 2043| v2043_8(void) = NoOp :
+# 2043| v2043_9(void) = ReturnIndirection[#this] : &:r2043_6, ~m?
+# 2043| v2043_10(void) = ReturnVoid :
+# 2043| v2043_11(void) = AliasedUse : ~m?
+# 2043| v2043_12(void) = ExitFunction :
+
+# 2046| void Derived2::Derived2()
+# 2046| Block 0
+# 2046| v2046_1(void) = EnterFunction :
+# 2046| mu2046_2(unknown) = AliasedDefinition :
+# 2046| mu2046_3(unknown) = InitializeNonLocal :
+# 2046| r2046_4(glval) = VariableAddress[#this] :
+# 2046| mu2046_5(glval) = InitializeParameter[#this] : &:r2046_4
+# 2046| r2046_6(glval) = Load[#this] : &:r2046_4, ~m?
+# 2046| mu2046_7(Derived2) = InitializeIndirection[#this] : &:r2046_6
+# 2046| r2046_8(glval) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2046_5
+# 2046| r2046_9(glval) = FunctionAddress[Base2] :
+# 2046| v2046_10(void) = Call[Base2] : func:r2046_9, this:r2046_8
+# 2046| mu2046_11(unknown) = ^CallSideEffect : ~m?
+# 2046| mu2046_12(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2046_8
+# 2046| v2046_13(void) = NoOp :
+# 2046| v2046_14(void) = ReturnIndirection[#this] : &:r2046_6, ~m?
+# 2046| v2046_15(void) = ReturnVoid :
+# 2046| v2046_16(void) = AliasedUse : ~m?
+# 2046| v2046_17(void) = ExitFunction :
+
+# 2049| void Derived2::~Derived2()
+# 2049| Block 0
+# 2049| v2049_1(void) = EnterFunction :
+# 2049| mu2049_2(unknown) = AliasedDefinition :
+# 2049| mu2049_3(unknown) = InitializeNonLocal :
+# 2049| r2049_4(glval) = VariableAddress[#this] :
+# 2049| mu2049_5(glval) = InitializeParameter[#this] : &:r2049_4
+# 2049| r2049_6(glval) = Load[#this] : &:r2049_4, ~m?
+# 2049| mu2049_7(Derived2) = InitializeIndirection[#this] : &:r2049_6
+# 2049| v2049_8(void) = NoOp :
+# 2049| r2049_9(glval) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2049_5
+# 2049| r2049_10(glval) = FunctionAddress[~Base2] :
+# 2049| v2049_11(void) = Call[~Base2] : func:r2049_10, this:r2049_9
+# 2049| mu2049_12(unknown) = ^CallSideEffect : ~m?
+# 2049| v2049_13(void) = ReturnIndirection[#this] : &:r2049_6, ~m?
+# 2049| v2049_14(void) = ReturnVoid :
+# 2049| v2049_15(void) = AliasedUse : ~m?
+# 2049| v2049_16(void) = ExitFunction :
+
+# 2051| void Derived2::operator delete(void*)
+# 2051| Block 0
+# 2051| v2051_1(void) = EnterFunction :
+# 2051| mu2051_2(unknown) = AliasedDefinition :
+# 2051| mu2051_3(unknown) = InitializeNonLocal :
+# 2051| r2051_4(glval) = VariableAddress[p] :
+# 2051| mu2051_5(void *) = InitializeParameter[p] : &:r2051_4
+# 2051| r2051_6(void *) = Load[p] : &:r2051_4, ~m?
+# 2051| mu2051_7(unknown) = InitializeIndirection[p] : &:r2051_6
+# 2052| v2052_1(void) = NoOp :
+# 2051| v2051_8(void) = ReturnIndirection[p] : &:r2051_6, ~m?
+# 2051| v2051_9(void) = ReturnVoid :
+# 2051| v2051_10(void) = AliasedUse : ~m?
+# 2051| v2051_11(void) = ExitFunction :
+
+# 2056| int virtual_delete()
+# 2056| Block 0
+# 2056| v2056_1(void) = EnterFunction :
+# 2056| mu2056_2(unknown) = AliasedDefinition :
+# 2056| mu2056_3(unknown) = InitializeNonLocal :
+# 2058| r2058_1(glval) = VariableAddress[b1] :
+# 2058| r2058_2(glval) = FunctionAddress[operator new] :
+# 2058| r2058_3(unsigned long) = Constant[8] :
+# 2058| r2058_4(void *) = Call[operator new] : func:r2058_2, 0:r2058_3
+# 2058| mu2058_5(unknown) = ^CallSideEffect : ~m?
+# 2058| mu2058_6(unknown) = ^InitializeDynamicAllocation : &:r2058_4
+# 2058| r2058_7(Base2 *) = Convert : r2058_4
+# 2058| r2058_8(glval) = FunctionAddress[Base2] :
+# 2058| v2058_9(void) = Call[Base2] : func:r2058_8, this:r2058_7
+# 2058| mu2058_10(unknown) = ^CallSideEffect : ~m?
+# 2058| mu2058_11(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2058_7
+# 2058| mu2058_12(Base2 *) = Store[b1] : &:r2058_1, r2058_7
+# 2059| r2059_1(glval) = VirtualDeleteFunctionAddress :
+# 2059| r2059_2(glval) = VariableAddress[b1] :
+# 2059| r2059_3(Base2 *) = Load[b1] : &:r2059_2, ~m?
+# 2059| v2059_4(void) = Call[?] : func:r2059_1, 0:r2059_3
+# 2059| mu2059_5(unknown) = ^CallSideEffect : ~m?
+# 2061| r2061_1(glval) = VariableAddress[b2] :
+# 2061| r2061_2(glval) = FunctionAddress[operator new] :
+# 2061| r2061_3(unsigned long) = Constant[16] :
+# 2061| r2061_4(void *) = Call[operator new] : func:r2061_2, 0:r2061_3
+# 2061| mu2061_5(unknown) = ^CallSideEffect : ~m?
+# 2061| mu2061_6(unknown) = ^InitializeDynamicAllocation : &:r2061_4
+# 2061| r2061_7(Derived2 *) = Convert : r2061_4
+# 2061| r2061_8(glval) = FunctionAddress[Derived2] :
+# 2061| v2061_9(void) = Call[Derived2] : func:r2061_8, this:r2061_7
+# 2061| mu2061_10(unknown) = ^CallSideEffect : ~m?
+# 2061| mu2061_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2061_7
+# 2061| r2061_12(Base2 *) = ConvertToNonVirtualBase[Derived2 : Base2] : r2061_7
+# 2061| mu2061_13(Base2 *) = Store[b2] : &:r2061_1, r2061_12
+# 2062| r2062_1(glval) = VirtualDeleteFunctionAddress :
+# 2062| r2062_2(glval) = VariableAddress[b2] :
+# 2062| r2062_3(Base2 *) = Load[b2] : &:r2062_2, ~m?
+# 2062| v2062_4(void) = Call[?] : func:r2062_1, 0:r2062_3
+# 2062| mu2062_5(unknown) = ^CallSideEffect : ~m?
+# 2064| r2064_1(glval) = VariableAddress[d] :
+# 2064| r2064_2(glval) = FunctionAddress[operator new] :
+# 2064| r2064_3(unsigned long) = Constant[16] :
+# 2064| r2064_4(void *) = Call[operator new] : func:r2064_2, 0:r2064_3
+# 2064| mu2064_5(unknown) = ^CallSideEffect : ~m?
+# 2064| mu2064_6(unknown) = ^InitializeDynamicAllocation : &:r2064_4
+# 2064| r2064_7(Derived2 *) = Convert : r2064_4
+# 2064| r2064_8(glval) = FunctionAddress[Derived2] :
+# 2064| v2064_9(void) = Call[Derived2] : func:r2064_8, this:r2064_7
+# 2064| mu2064_10(unknown) = ^CallSideEffect : ~m?
+# 2064| mu2064_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2064_7
+# 2064| mu2064_12(Derived2 *) = Store[d] : &:r2064_1, r2064_7
+# 2065| r2065_1(glval) = VirtualDeleteFunctionAddress :
+# 2065| r2065_2(glval) = VariableAddress[d] :
+# 2065| r2065_3(Derived2 *) = Load[d] : &:r2065_2, ~m?
+# 2065| v2065_4(void) = Call[?] : func:r2065_1, 0:r2065_3
+# 2065| mu2065_5(unknown) = ^CallSideEffect : ~m?
+# 2066| v2066_1(void) = Unreached :
+
+# 2056| Block 1
+# 2056| r2056_4(glval) = VariableAddress[#return] :
+# 2056| v2056_5(void) = ReturnValue : &:r2056_4, ~m?
+# 2056| v2056_6(void) = AliasedUse : ~m?
+# 2056| v2056_7(void) = ExitFunction :
+
+# 2070| void test_constant_folding()
+# 2070| Block 0
+# 2070| v2070_1(void) = EnterFunction :
+# 2070| mu2070_2(unknown) = AliasedDefinition :
+# 2070| mu2070_3(unknown) = InitializeNonLocal :
+# 2071| r2071_1(glval) = VariableAddress[x] :
+# 2071| r2071_2(int) = Constant[116] :
+# 2071| mu2071_3(int) = Store[x] : &:r2071_1, r2071_2
+# 2072| r2072_1(glval) = FunctionAddress[test_constant_folding_use] :
+# 2072| r2072_2(int) = Constant[116] :
+# 2072| v2072_3(void) = Call[test_constant_folding_use] : func:r2072_1, 0:r2072_2
+# 2072| mu2072_4(unknown) = ^CallSideEffect : ~m?
+# 2073| v2073_1(void) = NoOp :
+# 2070| v2070_4(void) = ReturnVoid :
+# 2070| v2070_5(void) = AliasedUse : ~m?
+# 2070| v2070_6(void) = ExitFunction :
+
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0
diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp
index dfdb90ee690..8f3c2c1faef 100644
--- a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp
+++ b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp
@@ -10,7 +10,7 @@ void m(int i, bool cond, int x, int y) {
int seven = 7;
if (mul % c2 == seven) {
- mod(mul); // congruent 3 mod 42, 7 mod 43
+ mod(mul); // $ mod=0,3,42
}
int j = cond
@@ -19,13 +19,11 @@ void m(int i, bool cond, int x, int y) {
mod(j); // $ mod=0,3,4
if (x % c1 == 3 && y % c1 == 7) {
- // Need implies_v2
- mod(x + y); // $ MISSING: 0,10,42
+ mod(x + y); // $ mod=0,10,42
}
if (x % c1 == 3 && y % c1 == 7) {
- // Need implies_v2
- mod(x - y); // $ MISSING: mod=0,38,42
+ mod(x - y); // $ mod=0,38,42
}
if (cond) {
diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp
index df29578409b..825e02b8616 100644
--- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp
+++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp
@@ -1008,12 +1008,12 @@ label:
void test_overflow() {
const int x = 2147483647; // 2^31-1
- range(x);
+ range(x); // $ range===2147483647
const int y = 256;
- range(y);
+ range(y); // $ range===256
if ((x + y) <= 512) {
- range(x);
- range(y);
+ range(x); // $ range===2147483647
+ range(y); // $ range===256
range(x + y); // $ range===-2147483393
}
}
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected
index bfc99021d27..cfe71545293 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected
@@ -18,6 +18,7 @@ edges
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
+| test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a |
| test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a |
| test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... |
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
@@ -28,6 +29,8 @@ edges
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
+| test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p |
+| test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p |
nodes
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
@@ -51,6 +54,8 @@ nodes
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
+| test_free.cpp:83:12:83:12 | a | semmle.label | a |
+| test_free.cpp:85:12:85:12 | a | semmle.label | a |
| test_free.cpp:101:10:101:10 | a | semmle.label | a |
| test_free.cpp:103:10:103:10 | a | semmle.label | a |
| test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... |
@@ -63,6 +68,10 @@ nodes
| test_free.cpp:207:10:207:10 | a | semmle.label | a |
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
+| test_free.cpp:252:7:252:7 | p | semmle.label | p |
+| test_free.cpp:255:10:255:10 | p | semmle.label | p |
+| test_free.cpp:260:9:260:9 | p | semmle.label | p |
+| test_free.cpp:263:12:263:12 | p | semmle.label | p |
subpaths
#select
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -84,6 +93,7 @@ subpaths
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
+| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free |
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
@@ -94,3 +104,5 @@ subpaths
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
+| test_free.cpp:255:10:255:10 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
+| test_free.cpp:263:12:263:12 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
index 4eb9bb35587..a9aa883efad 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
@@ -92,6 +92,10 @@
| test_free.cpp:233:14:233:15 | * ... |
| test_free.cpp:239:14:239:15 | * ... |
| test_free.cpp:245:10:245:11 | * ... |
+| test_free.cpp:252:7:252:7 | p |
+| test_free.cpp:255:10:255:10 | p |
+| test_free.cpp:260:9:260:9 | p |
+| test_free.cpp:263:12:263:12 | p |
| virtual.cpp:18:10:18:10 | a |
| virtual.cpp:19:10:19:10 | c |
| virtual.cpp:38:10:38:10 | b |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected
index 827c207b659..298e86c37e3 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected
@@ -12,3 +12,5 @@
| test.cpp:157:3:157:26 | new[] | This memory is never freed. |
| test.cpp:169:14:169:19 | call to strdup | This memory is never freed. |
| test_free.cpp:167:15:167:21 | call to realloc | This memory is never freed. |
+| test_free.cpp:253:14:253:19 | call to malloc | This memory is never freed. |
+| test_free.cpp:261:6:261:12 | new | This memory is never freed. |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
index 16e74b982c1..6b125a106af 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
@@ -9,6 +9,7 @@ edges
| test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a |
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
+| test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a |
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
| test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a |
@@ -27,6 +28,8 @@ edges
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
+| test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p |
+| test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p |
nodes
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
@@ -41,6 +44,8 @@ nodes
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
| test_free.cpp:71:9:71:9 | a | semmle.label | a |
+| test_free.cpp:83:12:83:12 | a | semmle.label | a |
+| test_free.cpp:84:5:84:5 | a | semmle.label | a |
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
| test_free.cpp:91:5:91:5 | a | semmle.label | a |
@@ -63,6 +68,10 @@ nodes
| test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... |
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
+| test_free.cpp:252:7:252:7 | p | semmle.label | p |
+| test_free.cpp:254:6:254:6 | p | semmle.label | p |
+| test_free.cpp:260:9:260:9 | p | semmle.label | p |
+| test_free.cpp:262:6:262:6 | p | semmle.label | p |
subpaths
#select
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -75,6 +84,7 @@ subpaths
| test_free.cpp:45:5:45:5 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
+| test_free.cpp:84:5:84:5 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | Memory may have been previously freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
| test_free.cpp:96:9:96:9 | a | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | Memory may have been previously freed by $@. | test_free.cpp:95:5:95:8 | call to free | call to free |
@@ -93,3 +103,5 @@ subpaths
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
+| test_free.cpp:254:6:254:6 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p | Memory may have been previously freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
+| test_free.cpp:262:6:262:6 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p | Memory may have been previously freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
index 8ea72edd64c..3aaefb1e416 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
@@ -81,8 +81,8 @@ public:
void test_new1() {
A *a = new A();
delete(a);
- a->f(); // BAD [NOT DETECTED]
- delete(a); // BAD [NOT DETECTED]
+ a->f(); // BAD
+ delete(a); // BAD
}
void test_dereference1(A *a) {
@@ -244,4 +244,21 @@ void test_loop3(char ** a, char ** b) {
void test_deref(char **a) {
free(*a);
use(*a); // GOOD [FALSE POSITIVE]
+}
+
+// Refs
+
+void test_ref(char *&p) {
+ free(p);
+ p = (char *)malloc(sizeof(char)*10);
+ use(p); // GOOD [FALSE POSITIVE]
+ free(p); // GOOD [FALSE POSITIVE]
+}
+
+
+void test_ref_delete(int *&p) {
+ delete p;
+ p = new int;
+ use(p); // GOOD [FALSE POSITIVE]
+ delete p; // GOOD [FALSE POSITIVE]
}
\ No newline at end of file
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
index 7a1b76f7632..ae8073cf09f 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
@@ -2,9 +2,11 @@ edges
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
+| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection |
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
+| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:35:50:43 | envCflags indirection |
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected
index e1665c23315..56297693056 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected
@@ -4,38 +4,29 @@ edges
| test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] |
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] |
+| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:19:5:19:7 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] |
| test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string |
-| test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string indirection |
-| test.cpp:42:18:42:23 | string indirection | test.cpp:42:18:42:23 | string |
| test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string |
-| test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string indirection |
-| test.cpp:72:22:72:27 | string indirection | test.cpp:72:22:72:27 | string |
| test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string |
-| test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string indirection |
-| test.cpp:80:22:80:27 | string indirection | test.cpp:80:22:80:27 | string |
| test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] |
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:10:90:15 | str indirection [post update] [string] |
| test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] |
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] |
+| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:91:5:91:7 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] |
| test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string |
-| test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string indirection |
-| test.cpp:99:18:99:23 | string indirection | test.cpp:99:18:99:23 | string |
| test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string |
-| test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string indirection |
-| test.cpp:129:22:129:27 | string indirection | test.cpp:129:22:129:27 | string |
| test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string |
-| test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string indirection |
-| test.cpp:137:22:137:27 | string indirection | test.cpp:137:22:137:27 | string |
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] |
| test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] |
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
+| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:148:5:148:7 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] |
@@ -46,32 +37,14 @@ edges
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:203:17:203:19 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:207:17:207:19 | str indirection [string] |
| test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string |
-| test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string indirection |
-| test.cpp:152:18:152:23 | string indirection | test.cpp:152:18:152:23 | string |
| test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string |
-| test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string indirection |
-| test.cpp:154:18:154:23 | string indirection | test.cpp:154:18:154:23 | string |
| test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string |
-| test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string indirection |
-| test.cpp:156:18:156:23 | string indirection | test.cpp:156:18:156:23 | string |
| test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string |
-| test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string indirection |
-| test.cpp:175:22:175:27 | string indirection | test.cpp:175:22:175:27 | string |
| test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string |
-| test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string indirection |
-| test.cpp:187:22:187:27 | string indirection | test.cpp:187:22:187:27 | string |
| test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string |
-| test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string indirection |
-| test.cpp:195:22:195:27 | string indirection | test.cpp:195:22:195:27 | string |
| test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string |
-| test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string indirection |
-| test.cpp:199:22:199:27 | string indirection | test.cpp:199:22:199:27 | string |
| test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string |
-| test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string indirection |
-| test.cpp:203:22:203:27 | string indirection | test.cpp:203:22:203:27 | string |
| test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string |
-| test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string indirection |
-| test.cpp:207:22:207:27 | string indirection | test.cpp:207:22:207:27 | string |
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p |
| test.cpp:220:43:220:48 | call to malloc | test.cpp:222:15:222:20 | buffer |
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p |
@@ -83,8 +56,6 @@ edges
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer |
| test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] |
| test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:12:243:21 | string |
-| test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:16:243:21 | string indirection |
-| test.cpp:243:16:243:21 | string indirection | test.cpp:243:12:243:21 | string |
| test.cpp:249:20:249:27 | call to my_alloc | test.cpp:250:12:250:12 | p |
| test.cpp:256:17:256:22 | call to malloc | test.cpp:257:12:257:12 | p |
| test.cpp:262:22:262:27 | call to malloc | test.cpp:266:12:266:12 | p |
@@ -98,13 +69,10 @@ nodes
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | semmle.label | call to mk_string_t indirection [string] |
| test.cpp:42:13:42:15 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:42:18:42:23 | string | semmle.label | string |
-| test.cpp:42:18:42:23 | string indirection | semmle.label | string indirection |
| test.cpp:72:17:72:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:72:22:72:27 | string | semmle.label | string |
-| test.cpp:72:22:72:27 | string indirection | semmle.label | string indirection |
| test.cpp:80:17:80:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:80:22:80:27 | string | semmle.label | string |
-| test.cpp:80:22:80:27 | string indirection | semmle.label | string indirection |
| test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | semmle.label | mk_string_t_plus_one indirection [string] |
| test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... |
| test.cpp:90:10:90:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] |
@@ -113,44 +81,32 @@ nodes
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | semmle.label | call to mk_string_t_plus_one indirection [string] |
| test.cpp:99:13:99:15 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:99:18:99:23 | string | semmle.label | string |
-| test.cpp:99:18:99:23 | string indirection | semmle.label | string indirection |
| test.cpp:129:17:129:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:129:22:129:27 | string | semmle.label | string |
-| test.cpp:129:22:129:27 | string indirection | semmle.label | string indirection |
| test.cpp:137:17:137:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:137:22:137:27 | string | semmle.label | string |
-| test.cpp:137:22:137:27 | string indirection | semmle.label | string indirection |
| test.cpp:147:5:147:34 | ... = ... | semmle.label | ... = ... |
| test.cpp:147:10:147:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] |
| test.cpp:147:19:147:24 | call to malloc | semmle.label | call to malloc |
| test.cpp:148:5:148:7 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:152:13:152:15 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:152:18:152:23 | string | semmle.label | string |
-| test.cpp:152:18:152:23 | string indirection | semmle.label | string indirection |
| test.cpp:154:13:154:15 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:154:18:154:23 | string | semmle.label | string |
-| test.cpp:154:18:154:23 | string indirection | semmle.label | string indirection |
| test.cpp:156:13:156:15 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:156:18:156:23 | string | semmle.label | string |
-| test.cpp:156:18:156:23 | string indirection | semmle.label | string indirection |
| test.cpp:175:17:175:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:175:22:175:27 | string | semmle.label | string |
-| test.cpp:175:22:175:27 | string indirection | semmle.label | string indirection |
| test.cpp:187:17:187:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:187:22:187:27 | string | semmle.label | string |
-| test.cpp:187:22:187:27 | string indirection | semmle.label | string indirection |
| test.cpp:195:17:195:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:195:22:195:27 | string | semmle.label | string |
-| test.cpp:195:22:195:27 | string indirection | semmle.label | string indirection |
| test.cpp:199:17:199:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:199:22:199:27 | string | semmle.label | string |
-| test.cpp:199:22:199:27 | string indirection | semmle.label | string indirection |
| test.cpp:203:17:203:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:203:22:203:27 | string | semmle.label | string |
-| test.cpp:203:22:203:27 | string indirection | semmle.label | string indirection |
| test.cpp:207:17:207:19 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:207:22:207:27 | string | semmle.label | string |
-| test.cpp:207:22:207:27 | string indirection | semmle.label | string indirection |
| test.cpp:214:24:214:24 | p | semmle.label | p |
| test.cpp:216:10:216:10 | p | semmle.label | p |
| test.cpp:220:43:220:48 | call to malloc | semmle.label | call to malloc |
@@ -165,7 +121,6 @@ nodes
| test.cpp:242:22:242:27 | buffer | semmle.label | buffer |
| test.cpp:243:12:243:14 | str indirection [string] | semmle.label | str indirection [string] |
| test.cpp:243:12:243:21 | string | semmle.label | string |
-| test.cpp:243:16:243:21 | string indirection | semmle.label | string indirection |
| test.cpp:249:20:249:27 | call to my_alloc | semmle.label | call to my_alloc |
| test.cpp:250:12:250:12 | p | semmle.label | p |
| test.cpp:256:17:256:22 | call to malloc | semmle.label | call to malloc |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected
index b18019c0b49..82049fc9229 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected
@@ -2,16 +2,13 @@ edges
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
-| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection |
-| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection |
-| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src indirection |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src indirection |
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src indirection |
@@ -23,17 +20,14 @@ nodes
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
-| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
| overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument |
| overflowdestination.cpp:46:15:46:17 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:50:52:50:54 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection |
-| overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection |
-| overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument |
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src indirection | semmle.label | src indirection |
@@ -43,9 +37,6 @@ subpaths
| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
#select
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
-| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
-| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
-| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected
index 065c900c71f..272327331f8 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected
@@ -1,13 +1,10 @@
edges
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
-| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
nodes
| test2.cpp:110:3:110:6 | call to gets indirection | semmle.label | call to gets indirection |
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
-| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
subpaths
#select
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets indirection | test2.cpp:110:3:110:6 | call to gets indirection | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets indirection | user input (string read by gets) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
-| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected
index d5a39f2465c..ba2e1dc5834 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected
@@ -1,6 +1,5 @@
edges
| test.cpp:11:26:11:28 | url indirection | test.cpp:15:30:15:32 | url indirection |
-| test.cpp:11:26:11:28 | url indirection | test.cpp:15:30:15:32 | url indirection |
| test.cpp:24:13:24:17 | url_g indirection | test.cpp:38:11:38:15 | url_g indirection |
| test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:24:13:24:17 | url_g indirection |
| test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:24:13:24:17 | url_g indirection |
@@ -23,7 +22,6 @@ edges
nodes
| test.cpp:11:26:11:28 | url indirection | semmle.label | url indirection |
| test.cpp:15:30:15:32 | url indirection | semmle.label | url indirection |
-| test.cpp:15:30:15:32 | url indirection | semmle.label | url indirection |
| test.cpp:24:13:24:17 | url_g indirection | semmle.label | url_g indirection |
| test.cpp:24:21:24:40 | http://example.com indirection | semmle.label | http://example.com indirection |
| test.cpp:24:21:24:40 | http://example.com indirection | semmle.label | http://example.com indirection |
@@ -47,27 +45,14 @@ subpaths
#select
| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
-| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected
index e95af7ceb10..200db037129 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected
@@ -11,6 +11,9 @@ edges
| test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data |
| test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data |
| test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data |
+| test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c |
+| test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... |
+| test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c |
| test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data |
| test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data |
| test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data |
@@ -19,6 +22,7 @@ edges
| test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data |
| test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data |
| test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data |
+| test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x |
nodes
| test.cpp:39:7:39:10 | data | semmle.label | data |
| test.cpp:39:7:39:10 | data | semmle.label | data |
@@ -38,6 +42,10 @@ nodes
| test.cpp:138:7:138:10 | data | semmle.label | data |
| test.cpp:138:7:138:10 | data | semmle.label | data |
| test.cpp:141:6:141:9 | data | semmle.label | data |
+| test.cpp:164:9:164:9 | c | semmle.label | c |
+| test.cpp:165:2:165:2 | c | semmle.label | c |
+| test.cpp:166:3:166:4 | * ... | semmle.label | * ... |
+| test.cpp:166:4:166:4 | c | semmle.label | c |
| test.cpp:181:7:181:10 | data | semmle.label | data |
| test.cpp:181:7:181:10 | data | semmle.label | data |
| test.cpp:186:6:186:9 | data | semmle.label | data |
@@ -50,6 +58,8 @@ nodes
| test.cpp:207:8:207:11 | data | semmle.label | data |
| test.cpp:209:6:209:9 | data | semmle.label | data |
| test.cpp:209:6:209:9 | data | semmle.label | data |
+| test.cpp:216:9:216:9 | x | semmle.label | x |
+| test.cpp:217:6:217:6 | x | semmle.label | x |
subpaths
#select
| test.cpp:41:6:41:9 | data | test.cpp:39:7:39:10 | data | test.cpp:41:6:41:9 | data | Memory may have been previously freed by $@. | test.cpp:39:2:39:5 | call to free | call to free |
@@ -64,6 +74,9 @@ subpaths
| test.cpp:130:6:130:9 | data | test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data | Memory may have been previously freed by $@. | test.cpp:127:2:127:5 | call to free | call to free |
| test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free |
| test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free |
+| test.cpp:165:2:165:2 | c | test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
+| test.cpp:166:3:166:4 | * ... | test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
+| test.cpp:166:4:166:4 | c | test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
| test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free |
| test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free |
| test.cpp:197:6:197:9 | data | test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data | Memory may have been previously freed by $@. | test.cpp:192:2:192:5 | call to free | call to free |
@@ -72,3 +85,4 @@ subpaths
| test.cpp:209:6:209:9 | data | test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:203:2:203:5 | call to free | call to free |
| test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free |
| test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free |
+| test.cpp:217:6:217:6 | x | test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x | Memory may have been previously freed by $@. | test.cpp:216:2:216:9 | delete | delete |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected
index a675c3a99d5..da20718ac12 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected
@@ -1,6 +1,5 @@
edges
| tests2.cpp:50:13:50:19 | global1 indirection | tests2.cpp:82:14:82:20 | global1 indirection |
-| tests2.cpp:50:13:50:19 | global1 indirection | tests2.cpp:82:14:82:20 | global1 indirection |
| tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:50:13:50:19 | global1 indirection |
| tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:26 | call to getenv indirection |
| tests2.cpp:64:13:64:18 | call to getenv indirection | tests2.cpp:64:13:64:26 | call to getenv indirection |
@@ -8,29 +7,24 @@ edges
| tests2.cpp:66:13:66:18 | call to getenv indirection | tests2.cpp:66:13:66:34 | call to getenv indirection |
| tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | tests2.cpp:81:14:81:19 | buffer indirection |
| tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection |
-| tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection |
-| tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection |
| tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection |
| tests2.cpp:109:3:109:36 | ... = ... indirection | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] |
| tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] | tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] |
| tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:109:3:109:36 | ... = ... indirection |
| tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:14:111:19 | ptr indirection |
| tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:17:111:19 | ptr indirection |
+| tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:17:111:19 | ptr indirection |
| tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:14:111:19 | ptr indirection |
| tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:17:111:19 | ptr indirection |
+| tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:17:111:19 | ptr indirection |
| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection |
| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection |
-| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection |
-| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection |
| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection |
| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection |
| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection |
| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection |
-| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection |
| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection |
| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection |
-| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection |
-| tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection |
| tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection |
| tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection |
nodes
@@ -52,13 +46,10 @@ nodes
| tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | semmle.label | call to mysql_get_client_info indirection |
| tests2.cpp:81:14:81:19 | buffer indirection | semmle.label | buffer indirection |
| tests2.cpp:82:14:82:20 | global1 indirection | semmle.label | global1 indirection |
-| tests2.cpp:82:14:82:20 | global1 indirection | semmle.label | global1 indirection |
| tests2.cpp:91:42:91:45 | str1 indirection | semmle.label | str1 indirection |
| tests2.cpp:93:14:93:17 | str1 indirection | semmle.label | str1 indirection |
-| tests2.cpp:93:14:93:17 | str1 indirection | semmle.label | str1 indirection |
| tests2.cpp:101:8:101:15 | call to getpwuid indirection | semmle.label | call to getpwuid indirection |
| tests2.cpp:102:14:102:15 | pw indirection | semmle.label | pw indirection |
-| tests2.cpp:102:14:102:15 | pw indirection | semmle.label | pw indirection |
| tests2.cpp:109:3:109:36 | ... = ... indirection | semmle.label | ... = ... indirection |
| tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] | semmle.label | c1 indirection [post update] [ptr indirection] |
| tests2.cpp:109:12:109:17 | call to getenv indirection | semmle.label | call to getenv indirection |
@@ -69,21 +60,16 @@ nodes
| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection |
-| tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection |
-| tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection |
-| tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection |
-| tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection |
| tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection |
| tests_sysconf.cpp:36:21:36:27 | confstr output argument | semmle.label | confstr output argument |
| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection |
| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection |
-| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection |
subpaths
#select
| tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:18 | call to getenv indirection | This operation exposes system data from $@. | tests2.cpp:63:13:63:18 | call to getenv indirection | call to getenv indirection |
@@ -97,25 +83,17 @@ subpaths
| tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | This operation exposes system data from $@. | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection |
| tests2.cpp:81:14:81:19 | buffer indirection | tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | tests2.cpp:81:14:81:19 | buffer indirection | This operation exposes system data from $@. | tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection |
| tests2.cpp:82:14:82:20 | global1 indirection | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:82:14:82:20 | global1 indirection | This operation exposes system data from $@. | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection |
-| tests2.cpp:82:14:82:20 | global1 indirection | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:82:14:82:20 | global1 indirection | This operation exposes system data from $@. | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection |
| tests2.cpp:93:14:93:17 | str1 indirection | tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 indirection | str1 indirection |
-| tests2.cpp:93:14:93:17 | str1 indirection | tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 indirection | str1 indirection |
-| tests2.cpp:102:14:102:15 | pw indirection | tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid indirection | call to getpwuid indirection |
| tests2.cpp:102:14:102:15 | pw indirection | tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid indirection | call to getpwuid indirection |
| tests2.cpp:111:14:111:19 | ptr indirection | tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:111:14:111:19 | ptr indirection | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv indirection | call to getenv indirection |
| tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:111:17:111:19 | ptr indirection | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
-| tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
-| tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
-| tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
-| tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
| tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection |
| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument |
| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument |
-| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected
index 4c37d69d3d6..79d0c0c8921 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected
@@ -6,20 +6,15 @@ edges
| tests.cpp:58:41:58:46 | call to getenv indirection | tests.cpp:58:41:58:62 | call to getenv indirection |
| tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:64 | call to getenv indirection |
| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:71:27:71:38 | global_token indirection |
-| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:71:27:71:38 | global_token indirection |
-| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:73:27:73:31 | maybe indirection |
| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:73:27:73:31 | maybe indirection |
| tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:62:7:62:18 | global_token indirection |
| tests.cpp:86:29:86:31 | msg indirection | tests.cpp:88:15:88:17 | msg indirection |
-| tests.cpp:86:29:86:31 | msg indirection | tests.cpp:88:15:88:17 | msg indirection |
| tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection |
| tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection |
| tests.cpp:97:13:97:34 | call to getenv indirection | tests.cpp:86:29:86:31 | msg indirection |
| tests.cpp:107:30:107:32 | msg indirection | tests.cpp:111:15:111:17 | tmp indirection |
-| tests.cpp:107:30:107:32 | msg indirection | tests.cpp:111:15:111:17 | tmp indirection |
| tests.cpp:114:30:114:32 | msg indirection | tests.cpp:119:7:119:12 | buffer indirection |
| tests.cpp:122:30:122:32 | msg indirection | tests.cpp:124:15:124:17 | msg indirection |
-| tests.cpp:122:30:122:32 | msg indirection | tests.cpp:124:15:124:17 | msg indirection |
| tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:131:14:131:35 | call to getenv indirection |
| tests.cpp:131:14:131:35 | call to getenv indirection | tests.cpp:107:30:107:32 | msg indirection |
| tests.cpp:132:14:132:19 | call to getenv indirection | tests.cpp:132:14:132:35 | call to getenv indirection |
@@ -28,8 +23,6 @@ edges
| tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:122:30:122:32 | msg indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection |
-| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection |
-| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection |
nodes
| tests.cpp:48:15:48:20 | call to getenv indirection | semmle.label | call to getenv indirection |
@@ -53,24 +46,19 @@ nodes
| tests.cpp:62:7:62:18 | global_token indirection | semmle.label | global_token indirection |
| tests.cpp:62:22:62:27 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:71:27:71:38 | global_token indirection | semmle.label | global_token indirection |
-| tests.cpp:71:27:71:38 | global_token indirection | semmle.label | global_token indirection |
-| tests.cpp:73:27:73:31 | maybe indirection | semmle.label | maybe indirection |
| tests.cpp:73:27:73:31 | maybe indirection | semmle.label | maybe indirection |
| tests.cpp:86:29:86:31 | msg indirection | semmle.label | msg indirection |
| tests.cpp:88:15:88:17 | msg indirection | semmle.label | msg indirection |
-| tests.cpp:88:15:88:17 | msg indirection | semmle.label | msg indirection |
| tests.cpp:97:13:97:18 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:97:13:97:18 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:97:13:97:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:97:13:97:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:107:30:107:32 | msg indirection | semmle.label | msg indirection |
| tests.cpp:111:15:111:17 | tmp indirection | semmle.label | tmp indirection |
-| tests.cpp:111:15:111:17 | tmp indirection | semmle.label | tmp indirection |
| tests.cpp:114:30:114:32 | msg indirection | semmle.label | msg indirection |
| tests.cpp:119:7:119:12 | buffer indirection | semmle.label | buffer indirection |
| tests.cpp:122:30:122:32 | msg indirection | semmle.label | msg indirection |
| tests.cpp:124:15:124:17 | msg indirection | semmle.label | msg indirection |
-| tests.cpp:124:15:124:17 | msg indirection | semmle.label | msg indirection |
| tests.cpp:131:14:131:19 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:131:14:131:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:132:14:132:19 | call to getenv indirection | semmle.label | call to getenv indirection |
@@ -81,8 +69,6 @@ nodes
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | semmle.label | call to getpwnam indirection |
| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection |
-| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection |
-| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection |
| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection |
subpaths
#select
@@ -99,21 +85,14 @@ subpaths
| tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:59:43:59:48 | call to getenv indirection | call to getenv indirection |
| tests.cpp:59:43:59:64 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:64 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:59:43:59:48 | call to getenv indirection | call to getenv indirection |
| tests.cpp:71:27:71:38 | global_token indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:71:27:71:38 | global_token indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection |
-| tests.cpp:71:27:71:38 | global_token indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:71:27:71:38 | global_token indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection |
| tests.cpp:73:27:73:31 | maybe indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:73:27:73:31 | maybe indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection |
-| tests.cpp:73:27:73:31 | maybe indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:73:27:73:31 | maybe indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection |
-| tests.cpp:88:15:88:17 | msg indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:88:15:88:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection |
| tests.cpp:88:15:88:17 | msg indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:88:15:88:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection |
| tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection |
| tests.cpp:97:13:97:34 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection |
| tests.cpp:111:15:111:17 | tmp indirection | tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:111:15:111:17 | tmp indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:131:14:131:19 | call to getenv indirection | call to getenv indirection |
-| tests.cpp:111:15:111:17 | tmp indirection | tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:111:15:111:17 | tmp indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:131:14:131:19 | call to getenv indirection | call to getenv indirection |
| tests.cpp:119:7:119:12 | buffer indirection | tests.cpp:132:14:132:19 | call to getenv indirection | tests.cpp:119:7:119:12 | buffer indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:19 | call to getenv indirection | call to getenv indirection |
| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection |
-| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection |
| tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection |
| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
-| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
-| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected
index 7acab8885ed..275e9e1fae9 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected
@@ -1,38 +1,25 @@
edges
| tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection |
-| tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection |
-| tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection |
| tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection |
| tests2.cpp:49:12:49:12 | call to SAXParser | tests2.cpp:51:2:51:2 | p indirection |
| tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection |
-| tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection |
-| tests3.cpp:35:16:35:20 | p_3_3 indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection |
| tests3.cpp:35:16:35:20 | p_3_3 indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection |
| tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:35:16:35:20 | p_3_3 indirection |
| tests3.cpp:48:16:48:20 | p_3_5 indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection |
-| tests3.cpp:48:16:48:20 | p_3_5 indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection |
| tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:48:16:48:20 | p_3_5 indirection |
| tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection |
-| tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection |
-| tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection |
| tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection |
| tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection |
-| tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection |
-| tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection |
| tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection |
| tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection |
-| tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection |
-| tests5.cpp:63:21:63:24 | g_p2 indirection | tests5.cpp:77:2:77:5 | g_p2 indirection |
| tests5.cpp:63:21:63:24 | g_p2 indirection | tests5.cpp:77:2:77:5 | g_p2 indirection |
| tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:63:21:63:24 | g_p2 indirection |
| tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection |
| tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection |
-| tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection |
| tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:85:2:85:2 | p indirection |
| tests5.cpp:85:2:85:2 | p indirection | tests5.cpp:86:2:86:2 | p indirection |
| tests5.cpp:86:2:86:2 | p indirection | tests5.cpp:88:2:88:2 | p indirection |
| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection |
-| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection |
| tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection |
| tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection |
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:35:23:35:43 | new indirection |
@@ -63,29 +50,22 @@ edges
nodes
| tests2.cpp:20:17:20:31 | call to SAXParser | semmle.label | call to SAXParser |
| tests2.cpp:22:2:22:2 | p indirection | semmle.label | p indirection |
-| tests2.cpp:22:2:22:2 | p indirection | semmle.label | p indirection |
| tests2.cpp:33:17:33:31 | call to SAXParser | semmle.label | call to SAXParser |
| tests2.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
-| tests2.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
| tests2.cpp:49:12:49:12 | call to SAXParser | semmle.label | call to SAXParser |
| tests2.cpp:51:2:51:2 | p indirection | semmle.label | p indirection |
| tests3.cpp:23:21:23:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection |
| tests3.cpp:25:2:25:2 | p indirection | semmle.label | p indirection |
-| tests3.cpp:25:2:25:2 | p indirection | semmle.label | p indirection |
| tests3.cpp:35:16:35:20 | p_3_3 indirection | semmle.label | p_3_3 indirection |
| tests3.cpp:35:24:35:56 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection |
| tests3.cpp:38:2:38:6 | p_3_3 indirection | semmle.label | p_3_3 indirection |
-| tests3.cpp:38:2:38:6 | p_3_3 indirection | semmle.label | p_3_3 indirection |
| tests3.cpp:48:16:48:20 | p_3_5 indirection | semmle.label | p_3_5 indirection |
| tests3.cpp:48:24:48:56 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection |
| tests3.cpp:56:2:56:6 | p_3_5 indirection | semmle.label | p_3_5 indirection |
-| tests3.cpp:56:2:56:6 | p_3_5 indirection | semmle.label | p_3_5 indirection |
| tests3.cpp:60:21:60:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection |
| tests3.cpp:63:2:63:2 | p indirection | semmle.label | p indirection |
-| tests3.cpp:63:2:63:2 | p indirection | semmle.label | p indirection |
| tests3.cpp:67:21:67:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection |
| tests3.cpp:70:2:70:2 | p indirection | semmle.label | p indirection |
-| tests3.cpp:70:2:70:2 | p indirection | semmle.label | p indirection |
| tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | semmle.label | XML_PARSE_NOENT |
| tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | semmle.label | XML_PARSE_DTDLOAD |
| tests4.cpp:46:34:46:68 | ... \| ... | semmle.label | ... \| ... |
@@ -93,26 +73,20 @@ nodes
| tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | semmle.label | XML_PARSE_DTDLOAD |
| tests5.cpp:27:25:27:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection |
| tests5.cpp:29:2:29:2 | p indirection | semmle.label | p indirection |
-| tests5.cpp:29:2:29:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:40:25:40:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection |
| tests5.cpp:43:2:43:2 | p indirection | semmle.label | p indirection |
-| tests5.cpp:43:2:43:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:55:25:55:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection |
| tests5.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
-| tests5.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:63:21:63:24 | g_p2 indirection | semmle.label | g_p2 indirection |
| tests5.cpp:70:17:70:30 | call to createLSParser indirection | semmle.label | call to createLSParser indirection |
| tests5.cpp:77:2:77:5 | g_p2 indirection | semmle.label | g_p2 indirection |
-| tests5.cpp:77:2:77:5 | g_p2 indirection | semmle.label | g_p2 indirection |
| tests5.cpp:81:25:81:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection |
| tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection |
-| tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:85:2:85:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:86:2:86:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:88:2:88:2 | p indirection | semmle.label | p indirection |
| tests5.cpp:89:2:89:2 | p indirection | semmle.label | p indirection |
-| tests5.cpp:89:2:89:2 | p indirection | semmle.label | p indirection |
| tests.cpp:15:23:15:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
| tests.cpp:17:2:17:2 | p indirection | semmle.label | p indirection |
| tests.cpp:28:23:28:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
@@ -152,19 +126,12 @@ nodes
subpaths
#select
| tests2.cpp:22:2:22:2 | p indirection | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:20:17:20:31 | call to SAXParser | XML parser |
-| tests2.cpp:22:2:22:2 | p indirection | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:20:17:20:31 | call to SAXParser | XML parser |
-| tests2.cpp:37:2:37:2 | p indirection | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:33:17:33:31 | call to SAXParser | XML parser |
| tests2.cpp:37:2:37:2 | p indirection | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:33:17:33:31 | call to SAXParser | XML parser |
| tests2.cpp:51:2:51:2 | p indirection | tests2.cpp:49:12:49:12 | call to SAXParser | tests2.cpp:51:2:51:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:49:12:49:12 | call to SAXParser | XML parser |
| tests3.cpp:25:2:25:2 | p indirection | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | XML parser |
-| tests3.cpp:25:2:25:2 | p indirection | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | XML parser |
-| tests3.cpp:38:2:38:6 | p_3_3 indirection | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | XML parser |
| tests3.cpp:38:2:38:6 | p_3_3 indirection | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | XML parser |
| tests3.cpp:56:2:56:6 | p_3_5 indirection | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | XML parser |
-| tests3.cpp:56:2:56:6 | p_3_5 indirection | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | XML parser |
| tests3.cpp:63:2:63:2 | p indirection | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | XML parser |
-| tests3.cpp:63:2:63:2 | p indirection | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | XML parser |
-| tests3.cpp:70:2:70:2 | p indirection | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | XML parser |
| tests3.cpp:70:2:70:2 | p indirection | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | XML parser |
| tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | XML parser |
| tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | XML parser |
@@ -172,16 +139,10 @@ subpaths
| tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:77:34:77:38 | flags | XML parser |
| tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | XML parser |
| tests5.cpp:29:2:29:2 | p indirection | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:27:25:27:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:29:2:29:2 | p indirection | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:27:25:27:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:43:2:43:2 | p indirection | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:40:25:40:38 | call to createLSParser indirection | XML parser |
| tests5.cpp:43:2:43:2 | p indirection | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:40:25:40:38 | call to createLSParser indirection | XML parser |
| tests5.cpp:59:2:59:2 | p indirection | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:55:25:55:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:59:2:59:2 | p indirection | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:55:25:55:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:77:2:77:5 | g_p2 indirection | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:70:17:70:30 | call to createLSParser indirection | XML parser |
| tests5.cpp:77:2:77:5 | g_p2 indirection | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:70:17:70:30 | call to createLSParser indirection | XML parser |
| tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser |
-| tests5.cpp:89:2:89:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:89:2:89:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser |
| tests5.cpp:89:2:89:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:89:2:89:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser |
| tests.cpp:17:2:17:2 | p indirection | tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:15:23:15:43 | call to XercesDOMParser | XML parser |
| tests.cpp:31:2:31:2 | p indirection | tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:28:23:28:43 | call to XercesDOMParser | XML parser |
diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj
index ecc67fa5695..590c03738b0 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj
@@ -8,12 +8,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers
-
+
diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
index 6edc9fdcd97..1083564dd26 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
@@ -3,9 +3,9 @@
net7.0
Semmle.Autobuild.CSharp
Semmle.Autobuild.CSharp
-
+
Exe
-
+
false
win-x64;linux-x64;osx-x64
enable
@@ -14,8 +14,8 @@
-
-
+
+
diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj
index 83c53552cc0..7a1f537fe75 100644
--- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj
+++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj
index c37242cd890..5bf70a9346b 100644
--- a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj
+++ b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj
@@ -24,7 +24,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs
index d6a19b9cd1a..f7b4ec3263b 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs
@@ -85,11 +85,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
- if (options.UseMscorlib)
- {
- UseReference(typeof(object).Assembly.Location);
- }
-
if (options.UseNuGet)
{
dllDirNames.Add(packageDirectory.DirInfo.FullName);
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs
index bf5800edb46..c669e649aee 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs
@@ -40,11 +40,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
///
bool ScanNetFrameworkDlls { get; }
- ///
- /// Whether to use mscorlib as a reference.
- ///
- bool UseMscorlib { get; }
-
///
/// Determine whether the given path should be excluded.
///
@@ -74,8 +69,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
public bool ScanNetFrameworkDlls { get; set; } = true;
- public bool UseMscorlib { get; set; } = true;
-
public bool ExcludesFile(string path) =>
Excludes.Any(path.Contains);
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs
index 9ad268fde31..6d52b410412 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs
@@ -10,16 +10,44 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly Version? preReleaseVersion;
private readonly string? preReleaseVersionType;
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
- public string FullPath
+
+ private string FullVersion
{
get
{
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
- var version = this.version + preRelease;
- return Path.Combine(dir, version);
+ return this.version + preRelease;
}
}
+ public string FullPath => Path.Combine(dir, FullVersion);
+
+ /**
+ * The full path to the reference assemblies for this runtime.
+ * This is the same as FullPath, except that we assume that the
+ * reference assemblies are in a directory called "packs" and
+ * the reference assemblies themselves are in a directory called
+ * ".Ref/ref".
+ * Example:
+ * FullPath: /usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.2
+ * FullPathReferenceAssemblies: /usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/7.0.2/ref
+ */
+ public string? FullPathReferenceAssemblies
+ {
+ get
+ {
+ var directories = dir.Split(Path.DirectorySeparatorChar);
+ if (directories.Length >= 2)
+ {
+ directories[^2] = "packs";
+ directories[^1] = $"{directories[^1]}.Ref";
+ return Path.Combine(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref");
+ }
+ return null;
+ }
+ }
+
+
public DotnetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
{
this.dir = dir;
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs
index cc7f77f5aac..9d1c6054d9b 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs
@@ -94,6 +94,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
+ private string? GetVersion(string framework)
+ {
+ if (NewestRuntimes.TryGetValue(framework, out var version))
+ {
+ var refAssemblies = version.FullPathReferenceAssemblies;
+ return Directory.Exists(refAssemblies)
+ ? refAssemblies
+ : version.FullPath;
+ }
+ return null;
+ }
+
///
/// Gets the .NET runtime location to use for extraction.
///
@@ -105,9 +117,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
// Location of the newest .NET Core Runtime.
- if (NewestRuntimes.TryGetValue(netCoreApp, out var netCoreVersion))
+ if (GetVersion(netCoreApp) is string path)
{
- return netCoreVersion.FullPath;
+ return path;
}
if (DesktopRuntimes.Any())
@@ -122,14 +134,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
///
/// Gets the ASP.NET runtime location to use for extraction, if one exists.
///
- public string? GetAspRuntime()
- {
- // Location of the newest ASP.NET Core Runtime.
- if (NewestRuntimes.TryGetValue(aspNetCoreApp, out var aspNetCoreVersion))
- {
- return aspNetCoreVersion.FullPath;
- }
- return null;
- }
+ public string? GetAspRuntime() => GetVersion(aspNetCoreApp);
}
}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs
index 451998396ed..1965296681a 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs
@@ -29,9 +29,6 @@ namespace Semmle.Extraction.CSharp.Standalone
case "all-references":
AnalyseCsProjFiles = !value;
return true;
- case "stdlib":
- dependencies.UseMscorlib = value;
- return true;
case "skip-dotnet":
dependencies.ScanNetFrameworkDlls = !value;
return true;
@@ -110,7 +107,7 @@ namespace Semmle.Extraction.CSharp.Standalone
///
/// Outputs the command line options to the console.
///
- public static void ShowHelp(System.IO.TextWriter output)
+ public static void ShowHelp(TextWriter output)
{
output.WriteLine("C# standalone extractor\n\nExtracts a C# project in the current directory without performing a build.\n");
output.WriteLine("Additional options:\n");
@@ -121,7 +118,6 @@ namespace Semmle.Extraction.CSharp.Standalone
output.WriteLine(" --dry-run Stop before extraction");
output.WriteLine(" --skip-nuget Do not download nuget packages");
output.WriteLine(" --all-references Use all references (default is to only use references in .csproj files)");
- output.WriteLine(" --nostdlib Do not link mscorlib.dll (use only for extracting mscorlib itself)");
output.WriteLine(" --threads:nnn Specify number of threads (default=CPU cores)");
output.WriteLine(" --verbose Produce more output");
output.WriteLine(" --pdb Cross-reference information from PDBs where available");
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj
index 38ba70ce285..525b1081bff 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj
+++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj
@@ -6,7 +6,7 @@
Semmle.Extraction.CSharp.Standalone
false
false
-
+
win-x64;linux-x64;osx-x64
enable
@@ -19,7 +19,7 @@
-
+
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj
index 4227a1df710..a06a1df38f2 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj
@@ -18,7 +18,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/csharp/extractor/Semmle.Extraction.Tests/Options.cs b/csharp/extractor/Semmle.Extraction.Tests/Options.cs
index 8b6704b95f9..226af193eb1 100644
--- a/csharp/extractor/Semmle.Extraction.Tests/Options.cs
+++ b/csharp/extractor/Semmle.Extraction.Tests/Options.cs
@@ -135,9 +135,8 @@ namespace Semmle.Extraction.Tests
public void StandaloneDefaults()
{
standaloneOptions = CSharp.Standalone.Options.Create(Array.Empty());
- Assert.Equal(0, standaloneOptions.Dependencies.DllDirs.Count);
+ Assert.Empty(standaloneOptions.Dependencies.DllDirs);
Assert.True(standaloneOptions.Dependencies.UseNuGet);
- Assert.True(standaloneOptions.Dependencies.UseMscorlib);
Assert.False(standaloneOptions.SkipExtraction);
Assert.Null(standaloneOptions.Dependencies.SolutionFile);
Assert.True(standaloneOptions.Dependencies.ScanNetFrameworkDlls);
@@ -147,12 +146,11 @@ namespace Semmle.Extraction.Tests
[Fact]
public void StandaloneOptions()
{
- standaloneOptions = CSharp.Standalone.Options.Create(new string[] { "--references:foo", "--silent", "--skip-nuget", "--skip-dotnet", "--exclude", "bar", "--nostdlib" });
+ standaloneOptions = CSharp.Standalone.Options.Create(new string[] { "--references:foo", "--silent", "--skip-nuget", "--skip-dotnet", "--exclude", "bar" });
Assert.Equal("foo", standaloneOptions.Dependencies.DllDirs[0]);
Assert.Equal("bar", standaloneOptions.Dependencies.Excludes[0]);
Assert.Equal(Verbosity.Off, standaloneOptions.Verbosity);
Assert.False(standaloneOptions.Dependencies.UseNuGet);
- Assert.False(standaloneOptions.Dependencies.UseMscorlib);
Assert.False(standaloneOptions.Dependencies.ScanNetFrameworkDlls);
Assert.False(standaloneOptions.Errors);
Assert.False(standaloneOptions.Help);
diff --git a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj
index 4e04bafc638..92bf46deb44 100644
--- a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj
+++ b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj
@@ -8,12 +8,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers
-
+
diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj
index 1c15b614ce4..433bb15ab1f 100644
--- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj
+++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj
@@ -12,9 +12,9 @@
TRACE;DEBUG;DEBUG_LABELS
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj
index cb362f6df33..384555bf18c 100644
--- a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj
+++ b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj
@@ -6,12 +6,12 @@
enable
-
-
+
+
all
runtime; build; native; contentfiles; analyzers
-
+
diff --git a/csharp/extractor/Semmle.Util/Semmle.Util.csproj b/csharp/extractor/Semmle.Util/Semmle.Util.csproj
index b2f15484886..894488f9f84 100644
--- a/csharp/extractor/Semmle.Util/Semmle.Util.csproj
+++ b/csharp/extractor/Semmle.Util/Semmle.Util.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
index 887b20471da..e17f85e34d1 100644
--- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
+++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.6.4
+
+No user-facing changes.
+
## 1.6.3
No user-facing changes.
diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md
new file mode 100644
index 00000000000..5c811dc4638
--- /dev/null
+++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md
@@ -0,0 +1,3 @@
+## 1.6.4
+
+No user-facing changes.
diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml
index 00b51441d88..1910e09d6a6 100644
--- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml
+++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 1.6.3
+lastReleaseVersion: 1.6.4
diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
index 5719e05afcf..c60da3557a0 100644
--- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
+++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
-version: 1.6.4-dev
+version: 1.6.4
groups:
- csharp
- solorigate
diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
index 887b20471da..e17f85e34d1 100644
--- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
+++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.6.4
+
+No user-facing changes.
+
## 1.6.3
No user-facing changes.
diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md
new file mode 100644
index 00000000000..5c811dc4638
--- /dev/null
+++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md
@@ -0,0 +1,3 @@
+## 1.6.4
+
+No user-facing changes.
diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml
index 00b51441d88..1910e09d6a6 100644
--- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml
+++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 1.6.3
+lastReleaseVersion: 1.6.4
diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml
index 2a3524ece6d..22e9e2f575b 100644
--- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml
+++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
-version: 1.6.4-dev
+version: 1.6.4
groups:
- csharp
- solorigate
diff --git a/csharp/ql/consistency-queries/DataFlowConsistency.ql b/csharp/ql/consistency-queries/DataFlowConsistency.ql
index 4ac709fd366..3fcda210961 100644
--- a/csharp/ql/consistency-queries/DataFlowConsistency.ql
+++ b/csharp/ql/consistency-queries/DataFlowConsistency.ql
@@ -1,12 +1,13 @@
import csharp
import cil
-import semmle.code.csharp.dataflow.internal.DataFlowPrivate
-import semmle.code.csharp.dataflow.internal.DataFlowPublic
-import semmle.code.csharp.dataflow.internal.DataFlowDispatch
-import semmle.code.csharp.dataflow.internal.DataFlowImplConsistency::Consistency
+private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
+private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-private class MyConsistencyConfiguration extends ConsistencyConfiguration {
- override predicate uniqueEnclosingCallableExclude(Node n) {
+private module Input implements InputSig {
+ private import CsharpDataFlow
+
+ predicate uniqueEnclosingCallableExclude(Node n) {
// TODO: Remove once static initializers are folded into the
// static constructors
exists(ControlFlow::Node cfn |
@@ -15,7 +16,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
)
}
- override predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
+ predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
// TODO: Remove once static initializers are folded into the
// static constructors
exists(ControlFlow::Node cfn |
@@ -24,25 +25,25 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
)
}
- override predicate uniqueNodeLocationExclude(Node n) {
+ predicate uniqueNodeLocationExclude(Node n) {
// Methods with multiple implementations
n instanceof ParameterNode
or
- this.missingLocationExclude(n)
+ missingLocationExclude(n)
}
- override predicate missingLocationExclude(Node n) {
+ predicate missingLocationExclude(Node n) {
// Some CIL methods are missing locations
n.asParameter() instanceof CIL::Parameter
}
- override predicate postWithInFlowExclude(Node n) {
+ predicate postWithInFlowExclude(Node n) {
n instanceof FlowSummaryNode
or
n.asExpr().(ObjectCreation).hasInitializer()
}
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
+ predicate argHasPostUpdateExclude(ArgumentNode n) {
n instanceof FlowSummaryNode
or
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
@@ -54,7 +55,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
n.asExpr() instanceof CIL::Expr
}
- override predicate postHasUniquePreExclude(PostUpdateNode n) {
+ predicate postHasUniquePreExclude(PostUpdateNode n) {
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
e != arg and
@@ -62,7 +63,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
)
}
- override predicate uniquePostUpdateExclude(Node n) {
+ predicate uniquePostUpdateExclude(Node n) {
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
e != arg and
@@ -70,12 +71,12 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
)
}
- override predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() }
-
- override predicate identityLocalStepExclude(Node n) { none() }
+ predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() }
}
-query predicate multipleToString(Node n, string s) {
+import MakeConsistency
+
+query predicate multipleToString(DataFlow::Node n, string s) {
s = strictconcat(n.toString(), ",") and
strictcount(n.toString()) > 1
}
diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj
index 5ea4974db7f..968726df756 100644
--- a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj
+++ b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj
@@ -8,10 +8,10 @@
-
+
-
-
+
+
diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj
index dfa6909c44b..95c7586e04e 100644
--- a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj
+++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj
@@ -10,10 +10,10 @@
-
-
-
-
+
+
+
+
diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md
index c96f22b5aa8..b16907bd011 100644
--- a/csharp/ql/lib/CHANGELOG.md
+++ b/csharp/ql/lib/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.7.4
+
+### Minor Analysis Improvements
+
+* The `--nostdlib` extractor option for the standalone extractor has been removed.
+
## 0.7.3
### Minor Analysis Improvements
diff --git a/csharp/ql/lib/change-notes/released/0.7.4.md b/csharp/ql/lib/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..9665706305a
--- /dev/null
+++ b/csharp/ql/lib/change-notes/released/0.7.4.md
@@ -0,0 +1,5 @@
+## 0.7.4
+
+### Minor Analysis Improvements
+
+* The `--nostdlib` extractor option for the standalone extractor has been removed.
diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/csharp/ql/lib/codeql-pack.release.yml
+++ b/csharp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml
index ba47a23065f..6bc467079d9 100644
--- a/csharp/ql/lib/qlpack.yml
+++ b/csharp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-all
-version: 0.7.4-dev
+version: 0.7.4
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
diff --git a/csharp/ql/lib/semmle/code/cil/Stubs.qll b/csharp/ql/lib/semmle/code/cil/Stubs.qll
index afe95d3ae77..7617119e617 100644
--- a/csharp/ql/lib/semmle/code/cil/Stubs.qll
+++ b/csharp/ql/lib/semmle/code/cil/Stubs.qll
@@ -32,12 +32,12 @@ private module Cached {
exists(Assembly asm |
asm = mi.getLocation() and
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
- not exists(MethodImplementation better | mi.getMethod() = better.getMethod() |
- mi.getNumberOfInstructions() < better.getNumberOfInstructions()
- or
- mi.getNumberOfInstructions() = better.getNumberOfInstructions() and
- asm.getFile().toString() > better.getLocation().getFile().toString()
- ) and
+ mi =
+ max(MethodImplementation impl |
+ mi.getMethod() = impl.getMethod()
+ |
+ impl order by impl.getNumberOfInstructions(), impl.getLocation().getFile().toString() desc
+ ) and
exists(mi.getAnInstruction())
)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
index 9f6ff2ce17f..0c57c2cea3b 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
@@ -109,8 +109,8 @@ private module Cached {
TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) {
cfn.getAstNode() = dc
} or
- TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) {
- transitiveCapturedCallTarget(cfn, target)
+ TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn) {
+ transitiveCapturedCallTarget(cfn, _)
} or
TCilCall(CIL::Call call) {
// No need to include calls that are compiled from source
@@ -389,11 +389,12 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
*/
class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCall {
private ControlFlow::Nodes::ElementNode cfn;
- private Callable target;
- TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn, target) }
+ TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn) }
- override DataFlowCallable getARuntimeTarget() { result.asCallable() = target }
+ override DataFlowCallable getARuntimeTarget() {
+ transitiveCapturedCallTarget(cfn, result.asCallable())
+ }
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
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 e7c11557a4c..308df381a12 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
@@ -1564,7 +1564,7 @@ private module OutNodes {
additionalCalls = false and call = csharpCall(_, cfn)
or
additionalCalls = true and
- call = TTransitiveCapturedCall(cfn, n.getEnclosingCallable())
+ call = TTransitiveCapturedCall(cfn)
)
}
diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md
index 0d165e05a25..0326272c6d8 100644
--- a/csharp/ql/src/CHANGELOG.md
+++ b/csharp/ql/src/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.7.4
+
+No user-facing changes.
+
## 0.7.3
No user-facing changes.
diff --git a/csharp/ql/src/change-notes/released/0.7.4.md b/csharp/ql/src/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..1b33df9cb1e
--- /dev/null
+++ b/csharp/ql/src/change-notes/released/0.7.4.md
@@ -0,0 +1,3 @@
+## 0.7.4
+
+No user-facing changes.
diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/csharp/ql/src/codeql-pack.release.yml
+++ b/csharp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/csharp/ql/src/experimental/ir/implementation/Opcode.qll b/csharp/ql/src/experimental/ir/implementation/Opcode.qll
index a9ecdf46984..c473969467d 100644
--- a/csharp/ql/src/experimental/ir/implementation/Opcode.qll
+++ b/csharp/ql/src/experimental/ir/implementation/Opcode.qll
@@ -55,6 +55,7 @@ private newtype TOpcode =
TVariableAddress() or
TFieldAddress() or
TFunctionAddress() or
+ TVirtualDeleteFunctionAddress() or
TElementsAddress() or
TConstant() or
TStringConstant() or
@@ -887,6 +888,15 @@ module Opcode {
final override string toString() { result = "FunctionAddress" }
}
+ /**
+ * The `Opcode` for a `VirtualDeleteFunctionAddress`.
+ *
+ * See the `VirtualDeleteFunctionAddressInstruction` documentation for more details.
+ */
+ class VirtualDeleteFunctionAddress extends Opcode, TVirtualDeleteFunctionAddress {
+ final override string toString() { result = "VirtualDeleteFunctionAddress" }
+ }
+
/**
* The `Opcode` for a `ConstantInstruction`.
*
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
index 1b5ea432946..2a3a6d3407a 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
+/**
+ * An instruction that returns the address of a "virtual" delete function.
+ *
+ * This function, which does not actually exist in the source code, is used to
+ * delete objects of a class with a virtual destructor. In that case the deacllocation
+ * function is selected at runtime based on the dynamic type of the object. So this
+ * function dynamically dispatches to the correct deallocation function.
+ * It also should pass in the required extra arguments to the deallocation function
+ * which may differ dynamically depending on the type of the object.
+ */
+class VirtualDeleteFunctionAddressInstruction extends Instruction {
+ VirtualDeleteFunctionAddressInstruction() {
+ this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+}
+
/**
* An instruction that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
index 1b5ea432946..2a3a6d3407a 100644
--- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
+/**
+ * An instruction that returns the address of a "virtual" delete function.
+ *
+ * This function, which does not actually exist in the source code, is used to
+ * delete objects of a class with a virtual destructor. In that case the deacllocation
+ * function is selected at runtime based on the dynamic type of the object. So this
+ * function dynamically dispatches to the correct deallocation function.
+ * It also should pass in the required extra arguments to the deallocation function
+ * which may differ dynamically depending on the type of the object.
+ */
+class VirtualDeleteFunctionAddressInstruction extends Instruction {
+ VirtualDeleteFunctionAddressInstruction() {
+ this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
+ }
+}
+
/**
* An instruction that initializes a parameter of the enclosing function with the value of the
* corresponding argument passed by the caller.
diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml
index a9d4c81c0f1..857555c05d8 100644
--- a/csharp/ql/src/qlpack.yml
+++ b/csharp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-queries
-version: 0.7.4-dev
+version: 0.7.4
groups:
- csharp
- queries
diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst
index 6ed36237e4c..1065d12e9f3 100644
--- a/docs/codeql/reusables/supported-versions-compilers.rst
+++ b/docs/codeql/reusables/supported-versions-compilers.rst
@@ -25,7 +25,7 @@
Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11",Not applicable,``.py``
Ruby [9]_,"up to 3.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
Swift [10]_,"Swift 5.4-5.8.1","Swift compiler","``.swift``"
- TypeScript [11]_,"2.6-5.1",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
+ TypeScript [11]_,"2.6-5.2",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
.. container:: footnote-group
diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md
index fb9e1f49e54..136789c4419 100644
--- a/go/ql/lib/CHANGELOG.md
+++ b/go/ql/lib/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.6.4
+
+### Minor Analysis Improvements
+
+* Added [http.Error](https://pkg.go.dev/net/http#Error) to XSS sanitzers.
+
## 0.6.3
No user-facing changes.
diff --git a/go/ql/lib/change-notes/released/0.6.4.md b/go/ql/lib/change-notes/released/0.6.4.md
new file mode 100644
index 00000000000..6c561f82177
--- /dev/null
+++ b/go/ql/lib/change-notes/released/0.6.4.md
@@ -0,0 +1,5 @@
+## 0.6.4
+
+### Minor Analysis Improvements
+
+* Added [http.Error](https://pkg.go.dev/net/http#Error) to XSS sanitzers.
diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml
index b7dafe32c5d..ced8cf94614 100644
--- a/go/ql/lib/codeql-pack.release.yml
+++ b/go/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.6.3
+lastReleaseVersion: 0.6.4
diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml
index d3765da2f89..6fa1f846bdd 100644
--- a/go/ql/lib/qlpack.yml
+++ b/go/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/go-all
-version: 0.6.4-dev
+version: 0.6.4
groups: go
dbscheme: go.dbscheme
extractor: go
diff --git a/go/ql/lib/semmle/go/security/Xss.qll b/go/ql/lib/semmle/go/security/Xss.qll
index 9003b766416..3310c7a420d 100644
--- a/go/ql/lib/semmle/go/security/Xss.qll
+++ b/go/ql/lib/semmle/go/security/Xss.qll
@@ -109,6 +109,18 @@ module SharedXss {
}
}
+ /**
+ * A http.Error function returns with the ContentType of text/plain, and is not a valid XSS sink
+ */
+ class ErrorSanitizer extends Sanitizer {
+ ErrorSanitizer() {
+ exists(Function f, DataFlow::CallNode call | call = f.getACall() |
+ f.hasQualifiedName("net/http", "Error") and
+ call.getArgument(1) = this
+ )
+ }
+ }
+
/**
* A regexp replacement involving an HTML meta-character, or a call to an escape
* function, viewed as a sanitizer for XSS vulnerabilities.
diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md
index cfe3163c6e9..7e8335b6aff 100644
--- a/go/ql/src/CHANGELOG.md
+++ b/go/ql/src/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.4
+
+No user-facing changes.
+
## 0.6.3
No user-facing changes.
diff --git a/go/ql/src/change-notes/released/0.6.4.md b/go/ql/src/change-notes/released/0.6.4.md
new file mode 100644
index 00000000000..7e98b0159fc
--- /dev/null
+++ b/go/ql/src/change-notes/released/0.6.4.md
@@ -0,0 +1,3 @@
+## 0.6.4
+
+No user-facing changes.
diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml
index b7dafe32c5d..ced8cf94614 100644
--- a/go/ql/src/codeql-pack.release.yml
+++ b/go/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.6.3
+lastReleaseVersion: 0.6.4
diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml
index a625c40a9c8..cd538178553 100644
--- a/go/ql/src/qlpack.yml
+++ b/go/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/go-queries
-version: 0.6.4-dev
+version: 0.6.4
groups:
- go
- queries
diff --git a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go
index a6f311e8458..d1ea413c3b9 100644
--- a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go
+++ b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go
@@ -25,9 +25,9 @@ func ServeJsonDirect(w http.ResponseWriter, r http.Request) {
func ErrTest(w http.ResponseWriter, r http.Request) {
cookie, err := r.Cookie("somecookie")
- w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled
- w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless
-
+ w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled
+ w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless
+ http.Error(w, fmt.Sprintf("Cookie result: %v", cookie), 500) // Good: only plain text is written.
file, header, err := r.FormFile("someFile")
content, err2 := ioutil.ReadAll(file)
w.Write([]byte(fmt.Sprintf("File content: %v", content))) // BAD: file content is user-controlled
diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py
index 009017b0073..c639209a930 100755
--- a/java/kotlin-extractor/build.py
+++ b/java/kotlin-extractor/build.py
@@ -92,6 +92,7 @@ def compile_to_dir(build_dir, srcs, classpath, java_classpath, output):
kotlin_arg_file = build_dir + '/kotlin.args'
kotlin_args = ['-Werror',
'-opt-in=kotlin.RequiresOptIn',
+ '-opt-in=org.jetbrains.kotlin.ir.symbols.IrSymbolInternals',
'-d', output,
'-module-name', 'codeql-kotlin-extractor',
'-no-reflect', '-no-stdlib',
@@ -168,7 +169,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output,
shutil.rmtree(tmp_src_dir)
shutil.copytree('src', tmp_src_dir)
- include_version_folder = tmp_src_dir + '/main/kotlin/utils/versions/to_include'
+ include_version_folder = tmp_src_dir + '/main/kotlin/utils/this_version'
os.makedirs(include_version_folder)
resource_dir = tmp_src_dir + '/main/resources/com/github/codeql'
@@ -192,11 +193,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output,
shutil.copytree(d, include_version_folder, dirs_exist_ok=True)
# remove all version folders:
- for version in kotlin_plugin_versions.many_versions:
- d = tmp_src_dir + '/main/kotlin/utils/versions/v_' + \
- version.replace('.', '_')
- if os.path.exists(d):
- shutil.rmtree(d)
+ shutil.rmtree(tmp_src_dir + '/main/kotlin/utils/versions')
srcs = find_sources(tmp_src_dir)
diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt
index c766d70df33..0e9524a8e43 100644
--- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt
+++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt
@@ -20,6 +20,7 @@ import java.nio.file.Files
import java.nio.file.Paths
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
+import com.github.codeql.utils.versions.usesK2
import com.semmle.util.files.FileUtil
import kotlin.system.exitProcess
@@ -97,6 +98,7 @@ class KotlinExtractorExtension(
private fun runExtractor(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
val startTimeMs = System.currentTimeMillis()
+ val usesK2 = usesK2(pluginContext)
// This default should be kept in sync with com.semmle.extractor.java.interceptors.KotlinInterceptor.initializeExtractionContext
val trapDir = File(System.getenv("CODEQL_EXTRACTOR_JAVA_TRAP_DIR").takeUnless { it.isNullOrEmpty() } ?: "kotlin-extractor/trap")
val compression_env_var = "CODEQL_EXTRACTOR_JAVA_OPTION_TRAP_COMPRESSION"
@@ -134,6 +136,7 @@ class KotlinExtractorExtension(
tw.writeCompilation_info(compilation, "Kotlin Compiler Version", KotlinCompilerVersion.getVersion() ?: "")
val extractor_name = this::class.java.getResource("extractor.name")?.readText() ?: ""
tw.writeCompilation_info(compilation, "Kotlin Extractor Name", extractor_name)
+ tw.writeCompilation_info(compilation, "Uses Kotlin 2", usesK2.toString())
if (compilationStartTime != null) {
tw.writeCompilation_compiler_times(compilation, -1.0, (System.currentTimeMillis()-compilationStartTime)/1000.0)
}
diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
index 55ec8c44dbb..022b71ca562 100644
--- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
@@ -107,7 +107,7 @@ open class KotlinFileExtractor(
fun extractFileContents(file: IrFile, id: Label) {
with("file", file) {
val locId = tw.getWholeFileLocation()
- val pkg = file.fqName.asString()
+ val pkg = file.packageFqName.asString()
val pkgId = extractPackage(pkg)
tw.writeHasLocation(id, locId)
tw.writeCupackage(id, pkgId)
@@ -1901,8 +1901,9 @@ open class KotlinFileExtractor(
verboseln("No match as didn't find target package")
return false
}
- if (targetPkg.fqName.asString() != pName) {
- verboseln("No match as package name is ${targetPkg.fqName.asString()}")
+ val targetName = targetPkg.packageFqName.asString()
+ if (targetName != pName) {
+ verboseln("No match as package name is $targetName")
return false
}
verboseln("Match")
@@ -2556,8 +2557,9 @@ open class KotlinFileExtractor(
verboseln("No match as didn't find target package")
return false
}
- if (targetPkg.fqName.asString() != pkgName) {
- verboseln("No match as package name is ${targetPkg.fqName.asString()} not $pkgName")
+ val targetName = targetPkg.packageFqName.asString()
+ if (targetName != pkgName) {
+ verboseln("No match as package name is $targetName not $pkgName")
return false
}
verboseln("Match")
diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
index 9c8f289eb0a..6d12d28cf9e 100644
--- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
@@ -5,6 +5,7 @@ import com.github.codeql.utils.versions.codeQlWithHasQuestionMark
import com.github.codeql.utils.versions.getFileClassFqName
import com.github.codeql.utils.versions.getKotlinType
import com.github.codeql.utils.versions.isRawType
+import com.github.codeql.utils.versions.packageFqName
import com.semmle.extractor.java.OdasaOutput
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.ir.*
@@ -83,7 +84,7 @@ open class KotlinUsesExtractor(
)
fun extractFileClass(f: IrFile): Label {
- val pkg = f.fqName.asString()
+ val pkg = f.packageFqName.asString()
val jvmName = getFileClassName(f)
val id = extractFileClass(pkg, jvmName)
if (tw.lm.fileClassLocationsExtracted.add(f)) {
@@ -848,7 +849,7 @@ open class KotlinUsesExtractor(
when(dp) {
is IrFile ->
if(canBeTopLevel) {
- usePackage(dp.fqName.asString())
+ usePackage(dp.packageFqName.asString())
} else {
extractFileClass(dp)
}
diff --git a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt
index 5fdf073813d..7cf1439b56a 100644
--- a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt
+++ b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt
@@ -276,8 +276,8 @@ class MetaAnnotationSupport(private val logger: FileLogger, private val pluginCo
run { logger.warnElement("Expected property's parent class to have a receiver parameter", parentClass); return }
val newParam = copyParameterToFunction(thisReceiever, this)
dispatchReceiverParameter = newParam
- body = factory.createBlockBody(
- UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
+ body = factory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply({
+ this.statements.add(
IrReturnImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
pluginContext.irBuiltIns.nothingType,
@@ -294,7 +294,7 @@ class MetaAnnotationSupport(private val logger: FileLogger, private val pluginCo
)
)
)
- )
+ })
}
}
diff --git a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
index a14b0c138db..738d44c7adf 100644
--- a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
+++ b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
@@ -8,11 +8,12 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.name.FqName
import com.github.codeql.utils.*
+import com.github.codeql.utils.versions.packageFqName
class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContext) {
fun getPrimitiveInfo(s: IrSimpleType) =
s.classOrNull?.let {
- if ((it.owner.parent as? IrPackageFragment)?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME)
+ if ((it.owner.parent as? IrPackageFragment)?.packageFqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME)
mapping[it.owner.name]
else
null
diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt
index ad4aaf60936..6a6b67b20aa 100644
--- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt
@@ -3,8 +3,8 @@ package com.github.codeql.comments
import com.github.codeql.*
import com.github.codeql.utils.IrVisitorLookup
import com.github.codeql.utils.isLocalFunction
+import com.github.codeql.utils.Psi2IrFacade
import com.github.codeql.utils.versions.getPsi2Ir
-import com.github.codeql.utils.versions.Psi2IrFacade
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.KotlinCompilerVersion
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
index 927d579ec34..30325af4b0f 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
@@ -2,6 +2,7 @@ package com.github.codeql
import com.github.codeql.utils.getJvmName
import com.github.codeql.utils.versions.getFileClassFqName
+import com.github.codeql.utils.versions.packageFqName
import com.intellij.openapi.vfs.StandardFileSystems
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
@@ -33,7 +34,7 @@ fun getFileClassName(f: IrFile) =
fun getIrElementBinaryName(that: IrElement): String {
if (that is IrFile) {
val shortName = getFileClassName(that)
- val pkg = that.fqName.asString()
+ val pkg = that.packageFqName.asString()
return if (pkg.isEmpty()) shortName else "$pkg.$shortName"
}
@@ -59,7 +60,7 @@ fun getIrElementBinaryName(that: IrElement): String {
.forEach {
when (it) {
is IrClass -> internalName.insert(0, getName(it) + "$")
- is IrPackageFragment -> it.fqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") }
+ is IrPackageFragment -> it.packageFqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") }
}
}
return internalName.toString()
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt
index d7da222442b..970c03da9cb 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt
@@ -1,6 +1,6 @@
package com.github.codeql.utils
-import com.github.codeql.utils.versions.Psi2IrFacade
+import com.github.codeql.utils.Psi2IrFacade
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt b/java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt
similarity index 88%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt
index 2c9e5f65e94..c9845b46895 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt
@@ -1,4 +1,4 @@
-package com.github.codeql.utils.versions
+package com.github.codeql.utils
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.ir.IrElement
@@ -8,4 +8,4 @@ import org.jetbrains.kotlin.psi.KtFile
interface Psi2IrFacade {
fun getKtFile(irFile: IrFile): KtFile?
fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement?
-}
\ No newline at end of file
+}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt
new file mode 100644
index 00000000000..b4f55b07cfd
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt
@@ -0,0 +1,4 @@
+package org.jetbrains.kotlin.ir.symbols
+
+@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
+annotation class IrSymbolInternals
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt
index 80120107478..2046b507bf8 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt
@@ -1,3 +1,5 @@
package com.github.codeql.utils.versions
+import com.github.codeql.utils.Psi2IrFacade
+
fun getPsi2Ir(): Psi2IrFacade? = null
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt
new file mode 100644
index 00000000000..39219d77730
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt
@@ -0,0 +1,7 @@
+package com.github.codeql.utils.versions
+
+import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+
+fun usesK2(@Suppress("UNUSED_PARAMETER") pluginContext: IrPluginContext): Boolean {
+ return false
+}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt
new file mode 100644
index 00000000000..87e67cd8368
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt
@@ -0,0 +1,10 @@
+package com.github.codeql.utils.versions
+
+import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.name.FqName
+
+val IrFile.packageFqName: FqName
+ get() = this.fqName
+
+val IrPackageFragment.packageFqName: FqName
+ get() = this.fqName
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt
index 73987106c55..dcd1c26afd2 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt
@@ -6,6 +6,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.psi.KtFile
+import com.github.codeql.utils.Psi2IrFacade
fun getPsi2Ir(): Psi2IrFacade? = Psi2Ir()
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt
new file mode 100644
index 00000000000..8d5e3345565
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt
@@ -0,0 +1,7 @@
+package com.github.codeql.utils.versions
+
+import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+
+fun usesK2(pluginContext: IrPluginContext): Boolean {
+ return pluginContext.languageVersionSettings.languageVersion.usesK2
+}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt
new file mode 100644
index 00000000000..48829cc30c5
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt
@@ -0,0 +1,4 @@
+package com.github.codeql
+
+// The compiler provides the annotation class, so we don't need to do
+// anything
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt
new file mode 100644
index 00000000000..613d51c7cbf
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt
@@ -0,0 +1,3 @@
+package com.github.codeql
+
+// The compiler provides packageFqName, so we don't need to do anything
diff --git a/java/ql/automodel/src/CHANGELOG.md b/java/ql/automodel/src/CHANGELOG.md
new file mode 100644
index 00000000000..af7864fc7d5
--- /dev/null
+++ b/java/ql/automodel/src/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.3
+
+No user-facing changes.
diff --git a/java/ql/automodel/src/change-notes/released/0.0.3.md b/java/ql/automodel/src/change-notes/released/0.0.3.md
new file mode 100644
index 00000000000..af7864fc7d5
--- /dev/null
+++ b/java/ql/automodel/src/change-notes/released/0.0.3.md
@@ -0,0 +1,3 @@
+## 0.0.3
+
+No user-facing changes.
diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml
new file mode 100644
index 00000000000..a24b693d1e7
--- /dev/null
+++ b/java/ql/automodel/src/codeql-pack.release.yml
@@ -0,0 +1,2 @@
+---
+lastReleaseVersion: 0.0.3
diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml
index 851dbe69e82..514ab9d0896 100644
--- a/java/ql/automodel/src/qlpack.yml
+++ b/java/ql/automodel/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-automodel-queries
-version: 0.0.3-dev
+version: 0.0.3
groups:
- java
- automodel
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected
new file mode 100644
index 00000000000..b7d6dd6e972
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected
@@ -0,0 +1,7 @@
+| Number of files with extension jar | 1 |
+| Number of files with extension kt | 1 |
+| Number of lines of code | 2 |
+| Number of lines of code with extension kt | 2 |
+| Total number of lines | 3 |
+| Total number of lines with extension kt | 3 |
+| Uses Kotlin 2: false | 1 |
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml
new file mode 100644
index 00000000000..3b6ffa4a377
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml
@@ -0,0 +1,13 @@
+extensions:
+ - addsTo:
+ pack: codeql/java-queries
+ extensible: extractorInformationSkipKey
+ data:
+ # These will have unstable values, as they are dependent on the
+ # JDK that the test is run with, so filter them out:
+ - ["Number of files"]
+ - ["Number of files with extension class"]
+ # These depend on the Kotlin version you have installed
+ - ["Kotlin Compiler Version: %"]
+ - ["Kotlin Extractor Name: %"]
+
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref
new file mode 100644
index 00000000000..ff57e78a9d7
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref
@@ -0,0 +1 @@
+Telemetry/ExtractorInformation.ql
\ No newline at end of file
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt
new file mode 100644
index 00000000000..80fb3d3af6a
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt
@@ -0,0 +1,2 @@
+class SomeClass {
+}
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py
new file mode 100755
index 00000000000..4a0fa4efd23
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py
@@ -0,0 +1,3 @@
+from create_database_utils import *
+
+run_codeql_database_create(["kotlinc SomeClass.kt"], lang="java")
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected
new file mode 100644
index 00000000000..e1fe4c6ee39
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected
@@ -0,0 +1,3 @@
+| Number of files with extension jar | 1 |
+| Number of files with extension kt | 1 |
+| Uses Kotlin 2: true | 1 |
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml
new file mode 100644
index 00000000000..be02d9554f8
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml
@@ -0,0 +1,17 @@
+extensions:
+ - addsTo:
+ pack: codeql/java-queries
+ extensible: extractorInformationSkipKey
+ data:
+ # These will have unstable values, as they are dependent on the
+ # JDK that the test is run with, so filter them out:
+ - ["Number of files"]
+ - ["Number of files with extension class"]
+ # These depend on the Kotlin version you have installed
+ - ["Kotlin Compiler Version: %"]
+ - ["Kotlin Extractor Name: %"]
+ # Currently we get some diagnostics as Kotlin 2 support isn't complete.
+ # Ignore these, as the number probably isn't stable.
+ - ["Number of diagnostics from CodeQL Kotlin extractor with severity %"]
+ - ["Total number of diagnostics from CodeQL Kotlin extractor"]
+
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref
new file mode 100644
index 00000000000..ff57e78a9d7
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref
@@ -0,0 +1 @@
+Telemetry/ExtractorInformation.ql
\ No newline at end of file
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt
new file mode 100644
index 00000000000..80fb3d3af6a
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt
@@ -0,0 +1,2 @@
+class SomeClass {
+}
diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py
new file mode 100755
index 00000000000..c61bbf88860
--- /dev/null
+++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py
@@ -0,0 +1,3 @@
+from create_database_utils import *
+
+run_codeql_database_create(["kotlinc -language-version 2.0 SomeClass.kt"], lang="java")
diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md
index 42a5c07e826..eaec0383f13 100644
--- a/java/ql/lib/CHANGELOG.md
+++ b/java/ql/lib/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 0.7.4
+
+### New Features
+
+* Kotlin versions up to 1.9.10 are now supported.
+
+### Minor Analysis Improvements
+
+* Fixed the MaD signature specifications to use proper nested type names.
+* Added new sanitizer to Java command injection model
+* Added more dataflow models for JAX-RS.
+* The predicate `JaxWsEndpoint::getARemoteMethod` no longer requires the result to be annotated with `@WebMethod`. Instead, the requirements listed in the JAX-RPC Specification 1.1 for required parameter and return types are used. Applications using JAX-RS may see an increase in results.
+
## 0.7.3
### Major Analysis Improvements
diff --git a/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md b/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md
deleted file mode 100644
index 8b34698758b..00000000000
--- a/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Added more dataflow models for JAX-RS.
diff --git a/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md b/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md
deleted file mode 100644
index ca183d5d065..00000000000
--- a/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Added new sanitizer to Java command injection model
\ No newline at end of file
diff --git a/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md b/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md
deleted file mode 100644
index 0a804f1866f..00000000000
--- a/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Fixed the MaD signature specifications to use proper nested type names.
diff --git a/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md b/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md
deleted file mode 100644
index ee878bb11af..00000000000
--- a/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: feature
----
-* Kotlin versions up to 1.9.10 are now supported.
diff --git a/java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md b/java/ql/lib/change-notes/released/0.7.4.md
similarity index 50%
rename from java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md
rename to java/ql/lib/change-notes/released/0.7.4.md
index be19599c865..78491df85eb 100644
--- a/java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md
+++ b/java/ql/lib/change-notes/released/0.7.4.md
@@ -1,4 +1,12 @@
----
-category: minorAnalysis
----
+## 0.7.4
+
+### New Features
+
+* Kotlin versions up to 1.9.10 are now supported.
+
+### Minor Analysis Improvements
+
+* Fixed the MaD signature specifications to use proper nested type names.
+* Added new sanitizer to Java command injection model
+* Added more dataflow models for JAX-RS.
* The predicate `JaxWsEndpoint::getARemoteMethod` no longer requires the result to be annotated with `@WebMethod`. Instead, the requirements listed in the JAX-RPC Specification 1.1 for required parameter and return types are used. Applications using JAX-RS may see an increase in results.
diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/java/ql/lib/codeql-pack.release.yml
+++ b/java/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml
index e708ee160f2..f4c8b284176 100644
--- a/java/ql/lib/qlpack.yml
+++ b/java/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-all
-version: 0.7.4-dev
+version: 0.7.4
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java
diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll
index e154491f795..1dfa24fffac 100644
--- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll
@@ -3,297 +3,15 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import java
+private import DataFlowImplSpecific
+private import TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
-
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
- or
- none()
- }
-
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
- }
-
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
- )
- }
-
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
- }
-
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
+private module Input implements InputSig {
+ predicate argHasPostUpdateExclude(JavaDataFlow::ArgumentNode n) {
+ n.getType() instanceof ImmutableType or n instanceof Public::ImplicitVarargsArray
}
}
+
+module Consistency = MakeConsistency;
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 212232e077a..556baa60f96 100644
--- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
@@ -8,7 +8,6 @@ private import ContainerFlow
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.dataflow.FlowSummary
private import FlowSummaryImpl as FlowSummaryImpl
-private import DataFlowImplConsistency
private import DataFlowNodes
private import codeql.dataflow.VariableCapture as VariableCapture
import DataFlowNodes::Private
@@ -113,11 +112,6 @@ private module CaptureInput implements VariableCapture::InputSig {
VariableWrite() { super.getDestVar() = v }
CapturedVariable getVariable() { result = v }
-
- Expr getSource() {
- result = this.(VariableAssign).getSource() or
- result = this.(AssignOp)
- }
}
class VariableRead extends Expr instanceof RValue {
@@ -155,14 +149,27 @@ class CapturedParameter = CaptureInput::CapturedParameter;
module CaptureFlow = VariableCapture::Flow;
private CaptureFlow::ClosureNode asClosureNode(Node n) {
- result = n.(CaptureNode).getSynthesizedCaptureNode() or
- result.(CaptureFlow::ExprNode).getExpr() = n.asExpr() or
+ result = n.(CaptureNode).getSynthesizedCaptureNode()
+ or
+ result.(CaptureFlow::ExprNode).getExpr() = n.asExpr()
+ or
result.(CaptureFlow::ExprPostUpdateNode).getExpr() =
- n.(PostUpdateNode).getPreUpdateNode().asExpr() or
- result.(CaptureFlow::ParameterNode).getParameter() = n.asParameter() or
- result.(CaptureFlow::ThisParameterNode).getCallable() = n.(InstanceParameterNode).getCallable() or
+ n.(PostUpdateNode).getPreUpdateNode().asExpr()
+ or
+ result.(CaptureFlow::ParameterNode).getParameter() = n.asParameter()
+ or
+ result.(CaptureFlow::ThisParameterNode).getCallable() = n.(InstanceParameterNode).getCallable()
+ or
exprNode(result.(CaptureFlow::MallocNode).getClosureExpr()).(PostUpdateNode).getPreUpdateNode() =
n
+ or
+ exists(CaptureInput::VariableWrite write |
+ result.(CaptureFlow::VariableWriteSourceNode).getVariableWrite() = write
+ |
+ n.asExpr() = write.(VariableAssign).getSource()
+ or
+ n.asExpr() = write.(AssignOp)
+ )
}
private predicate captureStoreStep(Node node1, CapturedVariableContent c, Node node2) {
@@ -572,12 +579,6 @@ ContentApprox getContentApprox(Content c) {
c instanceof SyntheticFieldContent and result = TSyntheticFieldApproxContent()
}
-private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
- n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray
- }
-}
-
/**
* Holds if the the content `c` is a container.
*/
diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md
index 4c5b963ada7..76cd01f48eb 100644
--- a/java/ql/src/CHANGELOG.md
+++ b/java/ql/src/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.7.4
+
+### New Queries
+
+* Added the `java/trust-boundary-violation` query to detect trust boundary violations between HTTP requests and the HTTP session. Also added the `trust-boundary-violation` sink kind for sinks which may cross a trust boundary, such as calls to the `HttpSession#setAttribute` method.
+
+### Minor Analysis Improvements
+
+* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library.
+
## 0.7.3
No user-facing changes.
diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql
index 51990878a34..24cd705eee7 100644
--- a/java/ql/src/Telemetry/ExtractorInformation.ql
+++ b/java/ql/src/Telemetry/ExtractorInformation.ql
@@ -87,7 +87,7 @@ predicate extractorTotalDiagnostics(string key, int value) {
from string key, int value
where
- not extractorInformationSkipKey(key) and
+ not exists(string pattern | extractorInformationSkipKey(pattern) and key.matches(pattern)) and
(
compilationInfo(key, value) or
fileCount(key, value) or
diff --git a/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md b/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md
deleted file mode 100644
index 6f062a63e81..00000000000
--- a/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library.
diff --git a/java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md b/java/ql/src/change-notes/released/0.7.4.md
similarity index 50%
rename from java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md
rename to java/ql/src/change-notes/released/0.7.4.md
index 802e367bf10..c214e52bd23 100644
--- a/java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md
+++ b/java/ql/src/change-notes/released/0.7.4.md
@@ -1,5 +1,9 @@
----
-category: newQuery
----
+## 0.7.4
+
+### New Queries
+
* Added the `java/trust-boundary-violation` query to detect trust boundary violations between HTTP requests and the HTTP session. Also added the `trust-boundary-violation` sink kind for sinks which may cross a trust boundary, such as calls to the `HttpSession#setAttribute` method.
+### Minor Analysis Improvements
+
+* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library.
diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/java/ql/src/codeql-pack.release.yml
+++ b/java/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml
index b2a297894fa..8fadb6cf148 100644
--- a/java/ql/src/qlpack.yml
+++ b/java/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-queries
-version: 0.7.4-dev
+version: 0.7.4
groups:
- java
- queries
diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme
new file mode 100644
index 00000000000..c88c69174bd
--- /dev/null
+++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme
@@ -0,0 +1,1190 @@
+/*** Standard fragments ***/
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- JavaScript-specific part -*/
+
+@location = @location_default
+
+@sourceline = @locatable;
+
+filetype(
+ int file: @file ref,
+ string filetype: string ref
+)
+
+// top-level code fragments
+toplevels (unique int id: @toplevel,
+ int kind: int ref);
+
+is_externs (int toplevel: @toplevel ref);
+
+case @toplevel.kind of
+ 0 = @script
+| 1 = @inline_script
+| 2 = @event_handler
+| 3 = @javascript_url
+| 4 = @template_toplevel;
+
+is_module (int tl: @toplevel ref);
+is_nodejs (int tl: @toplevel ref);
+is_es2015_module (int tl: @toplevel ref);
+is_closure_module (int tl: @toplevel ref);
+
+@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag;
+toplevel_parent_xml_node(
+ unique int toplevel: @toplevel ref,
+ int xmlnode: @xml_node_with_code ref);
+
+xml_element_parent_expression(
+ unique int xmlnode: @xmlelement ref,
+ int expression: @expr ref,
+ int index: int ref);
+
+// statements
+#keyset[parent, idx]
+stmts (unique int id: @stmt,
+ int kind: int ref,
+ int parent: @stmt_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+stmt_containers (unique int stmt: @stmt ref,
+ int container: @stmt_container ref);
+
+jump_targets (unique int jump: @stmt ref,
+ int target: @stmt ref);
+
+@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer;
+@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration;
+
+case @stmt.kind of
+ 0 = @empty_stmt
+| 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @labeled_stmt
+| 5 = @break_stmt
+| 6 = @continue_stmt
+| 7 = @with_stmt
+| 8 = @switch_stmt
+| 9 = @return_stmt
+| 10 = @throw_stmt
+| 11 = @try_stmt
+| 12 = @while_stmt
+| 13 = @do_while_stmt
+| 14 = @for_stmt
+| 15 = @for_in_stmt
+| 16 = @debugger_stmt
+| 17 = @function_decl_stmt
+| 18 = @var_decl_stmt
+| 19 = @case
+| 20 = @catch_clause
+| 21 = @for_of_stmt
+| 22 = @const_decl_stmt
+| 23 = @let_stmt
+| 24 = @legacy_let_stmt
+| 25 = @for_each_stmt
+| 26 = @class_decl_stmt
+| 27 = @import_declaration
+| 28 = @export_all_declaration
+| 29 = @export_default_declaration
+| 30 = @export_named_declaration
+| 31 = @namespace_declaration
+| 32 = @import_equals_declaration
+| 33 = @export_assign_declaration
+| 34 = @interface_declaration
+| 35 = @type_alias_declaration
+| 36 = @enum_declaration
+| 37 = @external_module_declaration
+| 38 = @export_as_namespace_declaration
+| 39 = @global_augmentation_declaration
+| 40 = @using_decl_stmt
+;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt;
+
+@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration;
+
+@namespace_definition = @namespace_declaration | @enum_declaration;
+@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member;
+
+is_instantiated(unique int decl: @namespace_declaration ref);
+
+@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field;
+has_declare_keyword(unique int stmt: @declarable_node ref);
+
+is_for_await_of(unique int forof: @for_of_stmt ref);
+
+// expressions
+#keyset[parent, idx]
+exprs (unique int id: @expr,
+ int kind: int ref,
+ int parent: @expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @expr_or_type ref);
+
+enclosing_stmt (unique int expr: @expr_or_type ref,
+ int stmt: @stmt ref);
+
+expr_containers (unique int expr: @expr_or_type ref,
+ int container: @stmt_container ref);
+
+array_size (unique int ae: @arraylike ref,
+ int sz: int ref);
+
+is_delegating (int yield: @yield_expr ref);
+
+@expr_or_stmt = @expr | @stmt;
+@expr_or_type = @expr | @typeexpr;
+@expr_parent = @expr_or_stmt | @property | @function_typeexpr;
+@arraylike = @array_expr | @array_pattern;
+@type_annotation = @typeexpr | @jsdoc_type_expr;
+@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel;
+
+case @expr.kind of
+ 0 = @label
+| 1 = @null_literal
+| 2 = @boolean_literal
+| 3 = @number_literal
+| 4 = @string_literal
+| 5 = @regexp_literal
+| 6 = @this_expr
+| 7 = @array_expr
+| 8 = @obj_expr
+| 9 = @function_expr
+| 10 = @seq_expr
+| 11 = @conditional_expr
+| 12 = @new_expr
+| 13 = @call_expr
+| 14 = @dot_expr
+| 15 = @index_expr
+| 16 = @neg_expr
+| 17 = @plus_expr
+| 18 = @log_not_expr
+| 19 = @bit_not_expr
+| 20 = @typeof_expr
+| 21 = @void_expr
+| 22 = @delete_expr
+| 23 = @eq_expr
+| 24 = @neq_expr
+| 25 = @eqq_expr
+| 26 = @neqq_expr
+| 27 = @lt_expr
+| 28 = @le_expr
+| 29 = @gt_expr
+| 30 = @ge_expr
+| 31 = @lshift_expr
+| 32 = @rshift_expr
+| 33 = @urshift_expr
+| 34 = @add_expr
+| 35 = @sub_expr
+| 36 = @mul_expr
+| 37 = @div_expr
+| 38 = @mod_expr
+| 39 = @bitor_expr
+| 40 = @xor_expr
+| 41 = @bitand_expr
+| 42 = @in_expr
+| 43 = @instanceof_expr
+| 44 = @logand_expr
+| 45 = @logor_expr
+| 47 = @assign_expr
+| 48 = @assign_add_expr
+| 49 = @assign_sub_expr
+| 50 = @assign_mul_expr
+| 51 = @assign_div_expr
+| 52 = @assign_mod_expr
+| 53 = @assign_lshift_expr
+| 54 = @assign_rshift_expr
+| 55 = @assign_urshift_expr
+| 56 = @assign_or_expr
+| 57 = @assign_xor_expr
+| 58 = @assign_and_expr
+| 59 = @preinc_expr
+| 60 = @postinc_expr
+| 61 = @predec_expr
+| 62 = @postdec_expr
+| 63 = @par_expr
+| 64 = @var_declarator
+| 65 = @arrow_function_expr
+| 66 = @spread_element
+| 67 = @array_pattern
+| 68 = @object_pattern
+| 69 = @yield_expr
+| 70 = @tagged_template_expr
+| 71 = @template_literal
+| 72 = @template_element
+| 73 = @array_comprehension_expr
+| 74 = @generator_expr
+| 75 = @for_in_comprehension_block
+| 76 = @for_of_comprehension_block
+| 77 = @legacy_letexpr
+| 78 = @var_decl
+| 79 = @proper_varaccess
+| 80 = @class_expr
+| 81 = @super_expr
+| 82 = @newtarget_expr
+| 83 = @named_import_specifier
+| 84 = @import_default_specifier
+| 85 = @import_namespace_specifier
+| 86 = @named_export_specifier
+| 87 = @exp_expr
+| 88 = @assign_exp_expr
+| 89 = @jsx_element
+| 90 = @jsx_qualified_name
+| 91 = @jsx_empty_expr
+| 92 = @await_expr
+| 93 = @function_sent_expr
+| 94 = @decorator
+| 95 = @export_default_specifier
+| 96 = @export_namespace_specifier
+| 97 = @bind_expr
+| 98 = @external_module_reference
+| 99 = @dynamic_import
+| 100 = @expression_with_type_arguments
+| 101 = @prefix_type_assertion
+| 102 = @as_type_assertion
+| 103 = @export_varaccess
+| 104 = @decorator_list
+| 105 = @non_null_assertion
+| 106 = @bigint_literal
+| 107 = @nullishcoalescing_expr
+| 108 = @e4x_xml_anyname
+| 109 = @e4x_xml_static_attribute_selector
+| 110 = @e4x_xml_dynamic_attribute_selector
+| 111 = @e4x_xml_filter_expression
+| 112 = @e4x_xml_static_qualident
+| 113 = @e4x_xml_dynamic_qualident
+| 114 = @e4x_xml_dotdotexpr
+| 115 = @import_meta_expr
+| 116 = @assignlogandexpr
+| 117 = @assignlogorexpr
+| 118 = @assignnullishcoalescingexpr
+| 119 = @template_pipe_ref
+| 120 = @generated_code_expr
+| 121 = @satisfies_expr
+;
+
+@varaccess = @proper_varaccess | @export_varaccess;
+@varref = @var_decl | @varaccess;
+
+@identifier = @label | @varref | @type_identifier;
+
+@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal;
+
+@propaccess = @dot_expr | @index_expr;
+
+@invokeexpr = @new_expr | @call_expr;
+
+@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element;
+
+@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr;
+
+@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr;
+
+@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr;
+
+@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr;
+
+@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr;
+
+@pattern = @varref | @array_pattern | @object_pattern;
+
+@comprehension_expr = @array_comprehension_expr | @generator_expr;
+
+@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block;
+
+@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier;
+
+@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier;
+
+@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier;
+
+@type_assertion = @as_type_assertion | @prefix_type_assertion;
+
+@class_definition = @class_decl_stmt | @class_expr;
+@interface_definition = @interface_declaration | @interface_typeexpr;
+@class_or_interface = @class_definition | @interface_definition;
+
+@lexical_decl = @var_decl | @type_decl;
+@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access;
+@lexical_ref = @lexical_decl | @lexical_access;
+
+@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector;
+@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident;
+
+expr_contains_template_tag_location(
+ int expr: @expr ref,
+ int location: @location ref
+);
+
+@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file;
+
+template_placeholder_tag_info(
+ unique int node: @template_placeholder_tag,
+ int parentNode: @template_placeholder_tag_parent ref,
+ varchar(900) raw: string ref
+);
+
+// scopes
+scopes (unique int id: @scope,
+ int kind: int ref);
+
+case @scope.kind of
+ 0 = @global_scope
+| 1 = @function_scope
+| 2 = @catch_scope
+| 3 = @module_scope
+| 4 = @block_scope
+| 5 = @for_scope
+| 6 = @for_in_scope // for-of scopes work the same as for-in scopes
+| 7 = @comprehension_block_scope
+| 8 = @class_expr_scope
+| 9 = @namespace_scope
+| 10 = @class_decl_scope
+| 11 = @interface_scope
+| 12 = @type_alias_scope
+| 13 = @mapped_type_scope
+| 14 = @enum_scope
+| 15 = @external_module_scope
+| 16 = @conditional_type_scope;
+
+scopenodes (unique int node: @ast_node ref,
+ int scope: @scope ref);
+
+scopenesting (unique int inner: @scope ref,
+ int outer: @scope ref);
+
+// functions
+@function = @function_decl_stmt | @function_expr | @arrow_function_expr;
+
+@parameterized = @function | @catch_clause;
+@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr;
+
+is_generator (int fun: @function ref);
+has_rest_parameter (int fun: @function ref);
+is_async (int fun: @function ref);
+
+// variables and lexically scoped type names
+#keyset[scope, name]
+variables (unique int id: @variable,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_type_names (unique int id: @local_type_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_namespace_names (unique int id: @local_namespace_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+is_arguments_object (int id: @variable ref);
+
+@lexical_name = @variable | @local_type_name | @local_namespace_name;
+
+@bind_id = @varaccess | @local_var_type_access;
+bind (unique int id: @bind_id ref,
+ int decl: @variable ref);
+
+decl (unique int id: @var_decl ref,
+ int decl: @variable ref);
+
+@typebind_id = @local_type_access | @export_varaccess;
+typebind (unique int id: @typebind_id ref,
+ int decl: @local_type_name ref);
+
+@typedecl_id = @type_decl | @var_decl;
+typedecl (unique int id: @typedecl_id ref,
+ int decl: @local_type_name ref);
+
+namespacedecl (unique int id: @var_decl ref,
+ int decl: @local_namespace_name ref);
+
+@namespacebind_id = @local_namespace_access | @export_varaccess;
+namespacebind (unique int id: @namespacebind_id ref,
+ int decl: @local_namespace_name ref);
+
+
+// properties in object literals, property patterns in object patterns, and method declarations in classes
+#keyset[parent, index]
+properties (unique int id: @property,
+ int parent: @property_parent ref,
+ int index: int ref,
+ int kind: int ref,
+ varchar(900) tostring: string ref);
+
+case @property.kind of
+ 0 = @value_property
+| 1 = @property_getter
+| 2 = @property_setter
+| 3 = @jsx_attribute
+| 4 = @function_call_signature
+| 5 = @constructor_call_signature
+| 6 = @index_signature
+| 7 = @enum_member
+| 8 = @proper_field
+| 9 = @parameter_field
+| 10 = @static_initializer
+;
+
+@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration;
+@property_accessor = @property_getter | @property_setter;
+@call_signature = @function_call_signature | @constructor_call_signature;
+@field = @proper_field | @parameter_field;
+@field_or_vardeclarator = @field | @var_declarator;
+
+is_computed (int id: @property ref);
+is_method (int id: @property ref);
+is_static (int id: @property ref);
+is_abstract_member (int id: @property ref);
+is_const_enum (int id: @enum_declaration ref);
+is_abstract_class (int id: @class_decl_stmt ref);
+
+has_public_keyword (int id: @property ref);
+has_private_keyword (int id: @property ref);
+has_protected_keyword (int id: @property ref);
+has_readonly_keyword (int id: @property ref);
+has_type_keyword (int id: @type_keyword_operand ref);
+is_optional_member (int id: @property ref);
+has_definite_assignment_assertion (int id: @field_or_vardeclarator ref);
+is_optional_parameter_declaration (unique int parameter: @pattern ref);
+
+#keyset[constructor, param_index]
+parameter_fields(
+ unique int field: @parameter_field ref,
+ int constructor: @function_expr ref,
+ int param_index: int ref
+);
+
+// types
+#keyset[parent, idx]
+typeexprs (
+ unique int id: @typeexpr,
+ int kind: int ref,
+ int parent: @typeexpr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref
+);
+
+case @typeexpr.kind of
+ 0 = @local_type_access
+| 1 = @type_decl
+| 2 = @keyword_typeexpr
+| 3 = @string_literal_typeexpr
+| 4 = @number_literal_typeexpr
+| 5 = @boolean_literal_typeexpr
+| 6 = @array_typeexpr
+| 7 = @union_typeexpr
+| 8 = @indexed_access_typeexpr
+| 9 = @intersection_typeexpr
+| 10 = @parenthesized_typeexpr
+| 11 = @tuple_typeexpr
+| 12 = @keyof_typeexpr
+| 13 = @qualified_type_access
+| 14 = @generic_typeexpr
+| 15 = @type_label
+| 16 = @typeof_typeexpr
+| 17 = @local_var_type_access
+| 18 = @qualified_var_type_access
+| 19 = @this_var_type_access
+| 20 = @predicate_typeexpr
+| 21 = @interface_typeexpr
+| 22 = @type_parameter
+| 23 = @plain_function_typeexpr
+| 24 = @constructor_typeexpr
+| 25 = @local_namespace_access
+| 26 = @qualified_namespace_access
+| 27 = @mapped_typeexpr
+| 28 = @conditional_typeexpr
+| 29 = @infer_typeexpr
+| 30 = @import_type_access
+| 31 = @import_namespace_access
+| 32 = @import_var_type_access
+| 33 = @optional_typeexpr
+| 34 = @rest_typeexpr
+| 35 = @bigint_literal_typeexpr
+| 36 = @readonly_typeexpr
+| 37 = @template_literal_typeexpr
+;
+
+@typeref = @typeaccess | @type_decl;
+@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access;
+@typeexpr_parent = @expr | @stmt | @property | @typeexpr;
+@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr;
+@typeaccess = @local_type_access | @qualified_type_access | @import_type_access;
+@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access;
+@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access;
+@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access;
+
+@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr;
+
+// types
+types (
+ unique int id: @type,
+ int kind: int ref,
+ varchar(900) tostring: string ref
+);
+
+#keyset[parent, idx]
+type_child (
+ int child: @type ref,
+ int parent: @type ref,
+ int idx: int ref
+);
+
+case @type.kind of
+ 0 = @any_type
+| 1 = @string_type
+| 2 = @number_type
+| 3 = @union_type
+| 4 = @true_type
+| 5 = @false_type
+| 6 = @type_reference
+| 7 = @object_type
+| 8 = @canonical_type_variable_type
+| 9 = @typeof_type
+| 10 = @void_type
+| 11 = @undefined_type
+| 12 = @null_type
+| 13 = @never_type
+| 14 = @plain_symbol_type
+| 15 = @unique_symbol_type
+| 16 = @objectkeyword_type
+| 17 = @intersection_type
+| 18 = @tuple_type
+| 19 = @lexical_type_variable_type
+| 20 = @this_type
+| 21 = @number_literal_type
+| 22 = @string_literal_type
+| 23 = @unknown_type
+| 24 = @bigint_type
+| 25 = @bigint_literal_type
+;
+
+@boolean_literal_type = @true_type | @false_type;
+@symbol_type = @plain_symbol_type | @unique_symbol_type;
+@union_or_intersection_type = @union_type | @intersection_type;
+@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type;
+
+has_asserts_keyword(int node: @predicate_typeexpr ref);
+
+@typed_ast_node = @expr | @typeexpr | @function;
+ast_node_type(
+ unique int node: @typed_ast_node ref,
+ int typ: @type ref);
+
+declared_function_signature(
+ unique int node: @function ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_signature(
+ unique int node: @invokeexpr ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_overload_index(
+ unique int node: @invokeexpr ref,
+ int index: int ref
+);
+
+symbols (
+ unique int id: @symbol,
+ int kind: int ref,
+ varchar(900) name: string ref
+);
+
+symbol_parent (
+ unique int symbol: @symbol ref,
+ int parent: @symbol ref
+);
+
+symbol_module (
+ int symbol: @symbol ref,
+ varchar(900) moduleName: string ref
+);
+
+symbol_global (
+ int symbol: @symbol ref,
+ varchar(900) globalName: string ref
+);
+
+case @symbol.kind of
+ 0 = @root_symbol
+| 1 = @member_symbol
+| 2 = @other_symbol
+;
+
+@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type;
+@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration;
+
+ast_node_symbol(
+ unique int node: @ast_node_with_symbol ref,
+ int symbol: @symbol ref);
+
+type_symbol(
+ unique int typ: @type_with_symbol ref,
+ int symbol: @symbol ref);
+
+#keyset[typ, name]
+type_property(
+ int typ: @type ref,
+ varchar(900) name: string ref,
+ int propertyType: @type ref);
+
+type_alias(
+ unique int aliasType: @type ref,
+ int underlyingType: @type ref);
+
+@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type;
+@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type;
+type_literal_value(
+ unique int typ: @type_with_literal_value ref,
+ varchar(900) value: string ref);
+
+signature_types (
+ unique int id: @signature_type,
+ int kind: int ref,
+ varchar(900) tostring: string ref,
+ int type_parameters: int ref,
+ int required_params: int ref
+);
+
+is_abstract_signature(
+ unique int sig: @signature_type ref
+);
+
+signature_rest_parameter(
+ unique int sig: @signature_type ref,
+ int rest_param_arra_type: @type ref
+);
+
+case @signature_type.kind of
+ 0 = @function_signature_type
+| 1 = @constructor_signature_type
+;
+
+#keyset[typ, kind, index]
+type_contains_signature (
+ int typ: @type ref,
+ int kind: int ref, // constructor/call/index
+ int index: int ref, // ordering of overloaded signatures
+ int sig: @signature_type ref
+);
+
+#keyset[parent, index]
+signature_contains_type (
+ int child: @type ref,
+ int parent: @signature_type ref,
+ int index: int ref
+);
+
+#keyset[sig, index]
+signature_parameter_name (
+ int sig: @signature_type ref,
+ int index: int ref,
+ varchar(900) name: string ref
+);
+
+number_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+string_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+base_type_names(
+ int typeName: @symbol ref,
+ int baseTypeName: @symbol ref
+);
+
+self_types(
+ int typeName: @symbol ref,
+ int selfType: @type_reference ref
+);
+
+tuple_type_min_length(
+ unique int typ: @type ref,
+ int minLength: int ref
+);
+
+tuple_type_rest_index(
+ unique int typ: @type ref,
+ int index: int ref
+);
+
+// comments
+comments (unique int id: @comment,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(900) tostring: string ref);
+
+case @comment.kind of
+ 0 = @slashslash_comment
+| 1 = @slashstar_comment
+| 2 = @doc_comment
+| 3 = @html_comment_start
+| 4 = @htmlcommentend;
+
+@html_comment = @html_comment_start | @htmlcommentend;
+@line_comment = @slashslash_comment | @html_comment;
+@block_comment = @slashstar_comment | @doc_comment;
+
+// source lines
+lines (unique int id: @line,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(2) terminator: string ref);
+indentation (int file: @file ref,
+ int lineno: int ref,
+ varchar(1) indentChar: string ref,
+ int indentDepth: int ref);
+
+// JavaScript parse errors
+js_parse_errors (unique int id: @js_parse_error,
+ int toplevel: @toplevel ref,
+ varchar(900) message: string ref,
+ varchar(900) line: string ref);
+
+// regular expressions
+#keyset[parent, idx]
+regexpterm (unique int id: @regexpterm,
+ int kind: int ref,
+ int parent: @regexpparent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr;
+
+case @regexpterm.kind of
+ 0 = @regexp_alt
+| 1 = @regexp_seq
+| 2 = @regexp_caret
+| 3 = @regexp_dollar
+| 4 = @regexp_wordboundary
+| 5 = @regexp_nonwordboundary
+| 6 = @regexp_positive_lookahead
+| 7 = @regexp_negative_lookahead
+| 8 = @regexp_star
+| 9 = @regexp_plus
+| 10 = @regexp_opt
+| 11 = @regexp_range
+| 12 = @regexp_dot
+| 13 = @regexp_group
+| 14 = @regexp_normal_constant
+| 15 = @regexp_hex_escape
+| 16 = @regexp_unicode_escape
+| 17 = @regexp_dec_escape
+| 18 = @regexp_oct_escape
+| 19 = @regexp_ctrl_escape
+| 20 = @regexp_char_class_escape
+| 21 = @regexp_id_escape
+| 22 = @regexp_backref
+| 23 = @regexp_char_class
+| 24 = @regexp_char_range
+| 25 = @regexp_positive_lookbehind
+| 26 = @regexp_negative_lookbehind
+| 27 = @regexp_unicode_property_escape;
+
+regexp_parse_errors (unique int id: @regexp_parse_error,
+ int regexp: @regexpterm ref,
+ varchar(900) message: string ref);
+
+@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
+@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape;
+@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
+@regexp_constant = @regexp_normal_constant | @regexp_char_escape;
+@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead;
+@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind;
+@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind;
+@regexp_anchor = @regexp_dollar | @regexp_caret;
+
+is_greedy (int id: @regexp_quantifier ref);
+range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref);
+range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref);
+is_capture (unique int id: @regexp_group ref, int number: int ref);
+is_named_capture (unique int id: @regexp_group ref, string name: string ref);
+is_inverted (int id: @regexp_char_class ref);
+regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref);
+char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
+backref (unique int id: @regexp_backref ref, int value: int ref);
+named_backref (unique int id: @regexp_backref ref, string name: string ref);
+unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref);
+unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref);
+
+// tokens
+#keyset[toplevel, idx]
+tokeninfo (unique int id: @token,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ int idx: int ref,
+ varchar(900) value: string ref);
+
+case @token.kind of
+ 0 = @token_eof
+| 1 = @token_null_literal
+| 2 = @token_boolean_literal
+| 3 = @token_numeric_literal
+| 4 = @token_string_literal
+| 5 = @token_regular_expression
+| 6 = @token_identifier
+| 7 = @token_keyword
+| 8 = @token_punctuator;
+
+// associate comments with the token immediately following them (which may be EOF)
+next_token (int comment: @comment ref, int token: @token ref);
+
+// JSON
+#keyset[parent, idx]
+json (unique int id: @json_value,
+ int kind: int ref,
+ int parent: @json_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+json_literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @json_value ref);
+
+json_properties (int obj: @json_object ref,
+ varchar(900) property: string ref,
+ int value: @json_value ref);
+
+json_errors (unique int id: @json_parse_error,
+ varchar(900) message: string ref);
+
+json_locations(unique int locatable: @json_locatable ref,
+ int location: @location_default ref);
+
+case @json_value.kind of
+ 0 = @json_null
+| 1 = @json_boolean
+| 2 = @json_number
+| 3 = @json_string
+| 4 = @json_array
+| 5 = @json_object;
+
+@json_parent = @json_object | @json_array | @file;
+
+@json_locatable = @json_value | @json_parse_error;
+
+// locations
+@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr;
+
+@locatable = @file
+ | @ast_node
+ | @comment
+ | @line
+ | @js_parse_error | @regexp_parse_error
+ | @regexpterm
+ | @json_locatable
+ | @token
+ | @cfg_node
+ | @jsdoc | @jsdoc_type_expr | @jsdoc_tag
+ | @yaml_locatable
+ | @xmllocatable
+ | @configLocatable
+ | @template_placeholder_tag;
+
+hasLocation (unique int locatable: @locatable ref,
+ int location: @location ref);
+
+// CFG
+entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref);
+exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref);
+guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref);
+case @guard_node.kind of
+ 0 = @falsy_guard
+| 1 = @truthy_guard;
+@condition_guard = @falsy_guard | @truthy_guard;
+
+@synthetic_cfg_node = @entry_node | @exit_node | @guard_node;
+@cfg_node = @synthetic_cfg_node | @expr_parent;
+
+successor (int pred: @cfg_node ref, int succ: @cfg_node ref);
+
+// JSDoc comments
+jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref);
+#keyset[parent, idx]
+jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref,
+ int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref);
+jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+
+#keyset[parent, idx]
+jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
+ int kind: int ref,
+ int parent: @jsdoc_type_expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+case @jsdoc_type_expr.kind of
+ 0 = @jsdoc_any_type_expr
+| 1 = @jsdoc_null_type_expr
+| 2 = @jsdoc_undefined_type_expr
+| 3 = @jsdoc_unknown_type_expr
+| 4 = @jsdoc_void_type_expr
+| 5 = @jsdoc_named_type_expr
+| 6 = @jsdoc_applied_type_expr
+| 7 = @jsdoc_nullable_type_expr
+| 8 = @jsdoc_non_nullable_type_expr
+| 9 = @jsdoc_record_type_expr
+| 10 = @jsdoc_array_type_expr
+| 11 = @jsdoc_union_type_expr
+| 12 = @jsdoc_function_type_expr
+| 13 = @jsdoc_optional_type_expr
+| 14 = @jsdoc_rest_type_expr
+;
+
+#keyset[id, idx]
+jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref);
+jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref);
+jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref);
+
+@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag;
+
+jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref);
+
+@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property;
+
+@optionalchainable = @call_expr | @propaccess;
+
+isOptionalChaining(int id: @optionalchainable ref);
+
+/**
+ * The time taken for the extraction of a file.
+ * This table contains non-deterministic content.
+ *
+ * The sum of the `time` column for each (`file`, `timerKind`) pair
+ * is the total time taken for extraction of `file`. The `extractionPhase`
+ * column provides a granular view of the extraction time of the file.
+ */
+extraction_time(
+ int file : @file ref,
+ // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`.
+ int extractionPhase: int ref,
+ // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds
+ int timerKind: int ref,
+ float time: float ref
+)
+
+/**
+* Non-timing related data for the extraction of a single file.
+* This table contains non-deterministic content.
+*/
+extraction_data(
+ int file : @file ref,
+ // the absolute path to the cache file
+ varchar(900) cacheFile: string ref,
+ boolean fromCache: boolean ref,
+ int length: int ref
+)
+
+/*- YAML -*/
+
+#keyset[parent, idx]
+yaml (unique int id: @yaml_node,
+ int kind: int ref,
+ int parent: @yaml_node_parent ref,
+ int idx: int ref,
+ string tag: string ref,
+ string tostring: string ref);
+
+case @yaml_node.kind of
+ 0 = @yaml_scalar_node
+| 1 = @yaml_mapping_node
+| 2 = @yaml_sequence_node
+| 3 = @yaml_alias_node
+;
+
+@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node;
+
+@yaml_node_parent = @yaml_collection_node | @file;
+
+yaml_anchors (unique int node: @yaml_node ref,
+ string anchor: string ref);
+
+yaml_aliases (unique int alias: @yaml_alias_node ref,
+ string target: string ref);
+
+yaml_scalars (unique int scalar: @yaml_scalar_node ref,
+ int style: int ref,
+ string value: string ref);
+
+yaml_errors (unique int id: @yaml_error,
+ string message: string ref);
+
+yaml_locations(unique int locatable: @yaml_locatable ref,
+ int location: @location_default ref);
+
+@yaml_locatable = @yaml_node | @yaml_error;
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*- Configuration files with key value pairs -*/
+
+configs(
+ unique int id: @config
+);
+
+configNames(
+ unique int id: @configName,
+ int config: @config ref,
+ string name: string ref
+);
+
+configValues(
+ unique int id: @configValue,
+ int config: @config ref,
+ string value: string ref
+);
+
+configLocations(
+ int locatable: @configLocatable ref,
+ int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme
new file mode 100644
index 00000000000..8accf0f930b
--- /dev/null
+++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme
@@ -0,0 +1,1189 @@
+/*** Standard fragments ***/
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- JavaScript-specific part -*/
+
+@location = @location_default
+
+@sourceline = @locatable;
+
+filetype(
+ int file: @file ref,
+ string filetype: string ref
+)
+
+// top-level code fragments
+toplevels (unique int id: @toplevel,
+ int kind: int ref);
+
+is_externs (int toplevel: @toplevel ref);
+
+case @toplevel.kind of
+ 0 = @script
+| 1 = @inline_script
+| 2 = @event_handler
+| 3 = @javascript_url
+| 4 = @template_toplevel;
+
+is_module (int tl: @toplevel ref);
+is_nodejs (int tl: @toplevel ref);
+is_es2015_module (int tl: @toplevel ref);
+is_closure_module (int tl: @toplevel ref);
+
+@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag;
+toplevel_parent_xml_node(
+ unique int toplevel: @toplevel ref,
+ int xmlnode: @xml_node_with_code ref);
+
+xml_element_parent_expression(
+ unique int xmlnode: @xmlelement ref,
+ int expression: @expr ref,
+ int index: int ref);
+
+// statements
+#keyset[parent, idx]
+stmts (unique int id: @stmt,
+ int kind: int ref,
+ int parent: @stmt_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+stmt_containers (unique int stmt: @stmt ref,
+ int container: @stmt_container ref);
+
+jump_targets (unique int jump: @stmt ref,
+ int target: @stmt ref);
+
+@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer;
+@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration;
+
+case @stmt.kind of
+ 0 = @empty_stmt
+| 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @labeled_stmt
+| 5 = @break_stmt
+| 6 = @continue_stmt
+| 7 = @with_stmt
+| 8 = @switch_stmt
+| 9 = @return_stmt
+| 10 = @throw_stmt
+| 11 = @try_stmt
+| 12 = @while_stmt
+| 13 = @do_while_stmt
+| 14 = @for_stmt
+| 15 = @for_in_stmt
+| 16 = @debugger_stmt
+| 17 = @function_decl_stmt
+| 18 = @var_decl_stmt
+| 19 = @case
+| 20 = @catch_clause
+| 21 = @for_of_stmt
+| 22 = @const_decl_stmt
+| 23 = @let_stmt
+| 24 = @legacy_let_stmt
+| 25 = @for_each_stmt
+| 26 = @class_decl_stmt
+| 27 = @import_declaration
+| 28 = @export_all_declaration
+| 29 = @export_default_declaration
+| 30 = @export_named_declaration
+| 31 = @namespace_declaration
+| 32 = @import_equals_declaration
+| 33 = @export_assign_declaration
+| 34 = @interface_declaration
+| 35 = @type_alias_declaration
+| 36 = @enum_declaration
+| 37 = @external_module_declaration
+| 38 = @export_as_namespace_declaration
+| 39 = @global_augmentation_declaration
+;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt;
+
+@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration;
+
+@namespace_definition = @namespace_declaration | @enum_declaration;
+@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member;
+
+is_instantiated(unique int decl: @namespace_declaration ref);
+
+@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field;
+has_declare_keyword(unique int stmt: @declarable_node ref);
+
+is_for_await_of(unique int forof: @for_of_stmt ref);
+
+// expressions
+#keyset[parent, idx]
+exprs (unique int id: @expr,
+ int kind: int ref,
+ int parent: @expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @expr_or_type ref);
+
+enclosing_stmt (unique int expr: @expr_or_type ref,
+ int stmt: @stmt ref);
+
+expr_containers (unique int expr: @expr_or_type ref,
+ int container: @stmt_container ref);
+
+array_size (unique int ae: @arraylike ref,
+ int sz: int ref);
+
+is_delegating (int yield: @yield_expr ref);
+
+@expr_or_stmt = @expr | @stmt;
+@expr_or_type = @expr | @typeexpr;
+@expr_parent = @expr_or_stmt | @property | @function_typeexpr;
+@arraylike = @array_expr | @array_pattern;
+@type_annotation = @typeexpr | @jsdoc_type_expr;
+@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel;
+
+case @expr.kind of
+ 0 = @label
+| 1 = @null_literal
+| 2 = @boolean_literal
+| 3 = @number_literal
+| 4 = @string_literal
+| 5 = @regexp_literal
+| 6 = @this_expr
+| 7 = @array_expr
+| 8 = @obj_expr
+| 9 = @function_expr
+| 10 = @seq_expr
+| 11 = @conditional_expr
+| 12 = @new_expr
+| 13 = @call_expr
+| 14 = @dot_expr
+| 15 = @index_expr
+| 16 = @neg_expr
+| 17 = @plus_expr
+| 18 = @log_not_expr
+| 19 = @bit_not_expr
+| 20 = @typeof_expr
+| 21 = @void_expr
+| 22 = @delete_expr
+| 23 = @eq_expr
+| 24 = @neq_expr
+| 25 = @eqq_expr
+| 26 = @neqq_expr
+| 27 = @lt_expr
+| 28 = @le_expr
+| 29 = @gt_expr
+| 30 = @ge_expr
+| 31 = @lshift_expr
+| 32 = @rshift_expr
+| 33 = @urshift_expr
+| 34 = @add_expr
+| 35 = @sub_expr
+| 36 = @mul_expr
+| 37 = @div_expr
+| 38 = @mod_expr
+| 39 = @bitor_expr
+| 40 = @xor_expr
+| 41 = @bitand_expr
+| 42 = @in_expr
+| 43 = @instanceof_expr
+| 44 = @logand_expr
+| 45 = @logor_expr
+| 47 = @assign_expr
+| 48 = @assign_add_expr
+| 49 = @assign_sub_expr
+| 50 = @assign_mul_expr
+| 51 = @assign_div_expr
+| 52 = @assign_mod_expr
+| 53 = @assign_lshift_expr
+| 54 = @assign_rshift_expr
+| 55 = @assign_urshift_expr
+| 56 = @assign_or_expr
+| 57 = @assign_xor_expr
+| 58 = @assign_and_expr
+| 59 = @preinc_expr
+| 60 = @postinc_expr
+| 61 = @predec_expr
+| 62 = @postdec_expr
+| 63 = @par_expr
+| 64 = @var_declarator
+| 65 = @arrow_function_expr
+| 66 = @spread_element
+| 67 = @array_pattern
+| 68 = @object_pattern
+| 69 = @yield_expr
+| 70 = @tagged_template_expr
+| 71 = @template_literal
+| 72 = @template_element
+| 73 = @array_comprehension_expr
+| 74 = @generator_expr
+| 75 = @for_in_comprehension_block
+| 76 = @for_of_comprehension_block
+| 77 = @legacy_letexpr
+| 78 = @var_decl
+| 79 = @proper_varaccess
+| 80 = @class_expr
+| 81 = @super_expr
+| 82 = @newtarget_expr
+| 83 = @named_import_specifier
+| 84 = @import_default_specifier
+| 85 = @import_namespace_specifier
+| 86 = @named_export_specifier
+| 87 = @exp_expr
+| 88 = @assign_exp_expr
+| 89 = @jsx_element
+| 90 = @jsx_qualified_name
+| 91 = @jsx_empty_expr
+| 92 = @await_expr
+| 93 = @function_sent_expr
+| 94 = @decorator
+| 95 = @export_default_specifier
+| 96 = @export_namespace_specifier
+| 97 = @bind_expr
+| 98 = @external_module_reference
+| 99 = @dynamic_import
+| 100 = @expression_with_type_arguments
+| 101 = @prefix_type_assertion
+| 102 = @as_type_assertion
+| 103 = @export_varaccess
+| 104 = @decorator_list
+| 105 = @non_null_assertion
+| 106 = @bigint_literal
+| 107 = @nullishcoalescing_expr
+| 108 = @e4x_xml_anyname
+| 109 = @e4x_xml_static_attribute_selector
+| 110 = @e4x_xml_dynamic_attribute_selector
+| 111 = @e4x_xml_filter_expression
+| 112 = @e4x_xml_static_qualident
+| 113 = @e4x_xml_dynamic_qualident
+| 114 = @e4x_xml_dotdotexpr
+| 115 = @import_meta_expr
+| 116 = @assignlogandexpr
+| 117 = @assignlogorexpr
+| 118 = @assignnullishcoalescingexpr
+| 119 = @template_pipe_ref
+| 120 = @generated_code_expr
+| 121 = @satisfies_expr
+;
+
+@varaccess = @proper_varaccess | @export_varaccess;
+@varref = @var_decl | @varaccess;
+
+@identifier = @label | @varref | @type_identifier;
+
+@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal;
+
+@propaccess = @dot_expr | @index_expr;
+
+@invokeexpr = @new_expr | @call_expr;
+
+@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element;
+
+@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr;
+
+@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr;
+
+@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr;
+
+@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr;
+
+@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr;
+
+@pattern = @varref | @array_pattern | @object_pattern;
+
+@comprehension_expr = @array_comprehension_expr | @generator_expr;
+
+@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block;
+
+@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier;
+
+@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier;
+
+@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier;
+
+@type_assertion = @as_type_assertion | @prefix_type_assertion;
+
+@class_definition = @class_decl_stmt | @class_expr;
+@interface_definition = @interface_declaration | @interface_typeexpr;
+@class_or_interface = @class_definition | @interface_definition;
+
+@lexical_decl = @var_decl | @type_decl;
+@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access;
+@lexical_ref = @lexical_decl | @lexical_access;
+
+@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector;
+@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident;
+
+expr_contains_template_tag_location(
+ int expr: @expr ref,
+ int location: @location ref
+);
+
+@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file;
+
+template_placeholder_tag_info(
+ unique int node: @template_placeholder_tag,
+ int parentNode: @template_placeholder_tag_parent ref,
+ varchar(900) raw: string ref
+);
+
+// scopes
+scopes (unique int id: @scope,
+ int kind: int ref);
+
+case @scope.kind of
+ 0 = @global_scope
+| 1 = @function_scope
+| 2 = @catch_scope
+| 3 = @module_scope
+| 4 = @block_scope
+| 5 = @for_scope
+| 6 = @for_in_scope // for-of scopes work the same as for-in scopes
+| 7 = @comprehension_block_scope
+| 8 = @class_expr_scope
+| 9 = @namespace_scope
+| 10 = @class_decl_scope
+| 11 = @interface_scope
+| 12 = @type_alias_scope
+| 13 = @mapped_type_scope
+| 14 = @enum_scope
+| 15 = @external_module_scope
+| 16 = @conditional_type_scope;
+
+scopenodes (unique int node: @ast_node ref,
+ int scope: @scope ref);
+
+scopenesting (unique int inner: @scope ref,
+ int outer: @scope ref);
+
+// functions
+@function = @function_decl_stmt | @function_expr | @arrow_function_expr;
+
+@parameterized = @function | @catch_clause;
+@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr;
+
+is_generator (int fun: @function ref);
+has_rest_parameter (int fun: @function ref);
+is_async (int fun: @function ref);
+
+// variables and lexically scoped type names
+#keyset[scope, name]
+variables (unique int id: @variable,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_type_names (unique int id: @local_type_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_namespace_names (unique int id: @local_namespace_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+is_arguments_object (int id: @variable ref);
+
+@lexical_name = @variable | @local_type_name | @local_namespace_name;
+
+@bind_id = @varaccess | @local_var_type_access;
+bind (unique int id: @bind_id ref,
+ int decl: @variable ref);
+
+decl (unique int id: @var_decl ref,
+ int decl: @variable ref);
+
+@typebind_id = @local_type_access | @export_varaccess;
+typebind (unique int id: @typebind_id ref,
+ int decl: @local_type_name ref);
+
+@typedecl_id = @type_decl | @var_decl;
+typedecl (unique int id: @typedecl_id ref,
+ int decl: @local_type_name ref);
+
+namespacedecl (unique int id: @var_decl ref,
+ int decl: @local_namespace_name ref);
+
+@namespacebind_id = @local_namespace_access | @export_varaccess;
+namespacebind (unique int id: @namespacebind_id ref,
+ int decl: @local_namespace_name ref);
+
+
+// properties in object literals, property patterns in object patterns, and method declarations in classes
+#keyset[parent, index]
+properties (unique int id: @property,
+ int parent: @property_parent ref,
+ int index: int ref,
+ int kind: int ref,
+ varchar(900) tostring: string ref);
+
+case @property.kind of
+ 0 = @value_property
+| 1 = @property_getter
+| 2 = @property_setter
+| 3 = @jsx_attribute
+| 4 = @function_call_signature
+| 5 = @constructor_call_signature
+| 6 = @index_signature
+| 7 = @enum_member
+| 8 = @proper_field
+| 9 = @parameter_field
+| 10 = @static_initializer
+;
+
+@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration;
+@property_accessor = @property_getter | @property_setter;
+@call_signature = @function_call_signature | @constructor_call_signature;
+@field = @proper_field | @parameter_field;
+@field_or_vardeclarator = @field | @var_declarator;
+
+is_computed (int id: @property ref);
+is_method (int id: @property ref);
+is_static (int id: @property ref);
+is_abstract_member (int id: @property ref);
+is_const_enum (int id: @enum_declaration ref);
+is_abstract_class (int id: @class_decl_stmt ref);
+
+has_public_keyword (int id: @property ref);
+has_private_keyword (int id: @property ref);
+has_protected_keyword (int id: @property ref);
+has_readonly_keyword (int id: @property ref);
+has_type_keyword (int id: @type_keyword_operand ref);
+is_optional_member (int id: @property ref);
+has_definite_assignment_assertion (int id: @field_or_vardeclarator ref);
+is_optional_parameter_declaration (unique int parameter: @pattern ref);
+
+#keyset[constructor, param_index]
+parameter_fields(
+ unique int field: @parameter_field ref,
+ int constructor: @function_expr ref,
+ int param_index: int ref
+);
+
+// types
+#keyset[parent, idx]
+typeexprs (
+ unique int id: @typeexpr,
+ int kind: int ref,
+ int parent: @typeexpr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref
+);
+
+case @typeexpr.kind of
+ 0 = @local_type_access
+| 1 = @type_decl
+| 2 = @keyword_typeexpr
+| 3 = @string_literal_typeexpr
+| 4 = @number_literal_typeexpr
+| 5 = @boolean_literal_typeexpr
+| 6 = @array_typeexpr
+| 7 = @union_typeexpr
+| 8 = @indexed_access_typeexpr
+| 9 = @intersection_typeexpr
+| 10 = @parenthesized_typeexpr
+| 11 = @tuple_typeexpr
+| 12 = @keyof_typeexpr
+| 13 = @qualified_type_access
+| 14 = @generic_typeexpr
+| 15 = @type_label
+| 16 = @typeof_typeexpr
+| 17 = @local_var_type_access
+| 18 = @qualified_var_type_access
+| 19 = @this_var_type_access
+| 20 = @predicate_typeexpr
+| 21 = @interface_typeexpr
+| 22 = @type_parameter
+| 23 = @plain_function_typeexpr
+| 24 = @constructor_typeexpr
+| 25 = @local_namespace_access
+| 26 = @qualified_namespace_access
+| 27 = @mapped_typeexpr
+| 28 = @conditional_typeexpr
+| 29 = @infer_typeexpr
+| 30 = @import_type_access
+| 31 = @import_namespace_access
+| 32 = @import_var_type_access
+| 33 = @optional_typeexpr
+| 34 = @rest_typeexpr
+| 35 = @bigint_literal_typeexpr
+| 36 = @readonly_typeexpr
+| 37 = @template_literal_typeexpr
+;
+
+@typeref = @typeaccess | @type_decl;
+@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access;
+@typeexpr_parent = @expr | @stmt | @property | @typeexpr;
+@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr;
+@typeaccess = @local_type_access | @qualified_type_access | @import_type_access;
+@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access;
+@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access;
+@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access;
+
+@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr;
+
+// types
+types (
+ unique int id: @type,
+ int kind: int ref,
+ varchar(900) tostring: string ref
+);
+
+#keyset[parent, idx]
+type_child (
+ int child: @type ref,
+ int parent: @type ref,
+ int idx: int ref
+);
+
+case @type.kind of
+ 0 = @any_type
+| 1 = @string_type
+| 2 = @number_type
+| 3 = @union_type
+| 4 = @true_type
+| 5 = @false_type
+| 6 = @type_reference
+| 7 = @object_type
+| 8 = @canonical_type_variable_type
+| 9 = @typeof_type
+| 10 = @void_type
+| 11 = @undefined_type
+| 12 = @null_type
+| 13 = @never_type
+| 14 = @plain_symbol_type
+| 15 = @unique_symbol_type
+| 16 = @objectkeyword_type
+| 17 = @intersection_type
+| 18 = @tuple_type
+| 19 = @lexical_type_variable_type
+| 20 = @this_type
+| 21 = @number_literal_type
+| 22 = @string_literal_type
+| 23 = @unknown_type
+| 24 = @bigint_type
+| 25 = @bigint_literal_type
+;
+
+@boolean_literal_type = @true_type | @false_type;
+@symbol_type = @plain_symbol_type | @unique_symbol_type;
+@union_or_intersection_type = @union_type | @intersection_type;
+@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type;
+
+has_asserts_keyword(int node: @predicate_typeexpr ref);
+
+@typed_ast_node = @expr | @typeexpr | @function;
+ast_node_type(
+ unique int node: @typed_ast_node ref,
+ int typ: @type ref);
+
+declared_function_signature(
+ unique int node: @function ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_signature(
+ unique int node: @invokeexpr ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_overload_index(
+ unique int node: @invokeexpr ref,
+ int index: int ref
+);
+
+symbols (
+ unique int id: @symbol,
+ int kind: int ref,
+ varchar(900) name: string ref
+);
+
+symbol_parent (
+ unique int symbol: @symbol ref,
+ int parent: @symbol ref
+);
+
+symbol_module (
+ int symbol: @symbol ref,
+ varchar(900) moduleName: string ref
+);
+
+symbol_global (
+ int symbol: @symbol ref,
+ varchar(900) globalName: string ref
+);
+
+case @symbol.kind of
+ 0 = @root_symbol
+| 1 = @member_symbol
+| 2 = @other_symbol
+;
+
+@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type;
+@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration;
+
+ast_node_symbol(
+ unique int node: @ast_node_with_symbol ref,
+ int symbol: @symbol ref);
+
+type_symbol(
+ unique int typ: @type_with_symbol ref,
+ int symbol: @symbol ref);
+
+#keyset[typ, name]
+type_property(
+ int typ: @type ref,
+ varchar(900) name: string ref,
+ int propertyType: @type ref);
+
+type_alias(
+ unique int aliasType: @type ref,
+ int underlyingType: @type ref);
+
+@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type;
+@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type;
+type_literal_value(
+ unique int typ: @type_with_literal_value ref,
+ varchar(900) value: string ref);
+
+signature_types (
+ unique int id: @signature_type,
+ int kind: int ref,
+ varchar(900) tostring: string ref,
+ int type_parameters: int ref,
+ int required_params: int ref
+);
+
+is_abstract_signature(
+ unique int sig: @signature_type ref
+);
+
+signature_rest_parameter(
+ unique int sig: @signature_type ref,
+ int rest_param_arra_type: @type ref
+);
+
+case @signature_type.kind of
+ 0 = @function_signature_type
+| 1 = @constructor_signature_type
+;
+
+#keyset[typ, kind, index]
+type_contains_signature (
+ int typ: @type ref,
+ int kind: int ref, // constructor/call/index
+ int index: int ref, // ordering of overloaded signatures
+ int sig: @signature_type ref
+);
+
+#keyset[parent, index]
+signature_contains_type (
+ int child: @type ref,
+ int parent: @signature_type ref,
+ int index: int ref
+);
+
+#keyset[sig, index]
+signature_parameter_name (
+ int sig: @signature_type ref,
+ int index: int ref,
+ varchar(900) name: string ref
+);
+
+number_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+string_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+base_type_names(
+ int typeName: @symbol ref,
+ int baseTypeName: @symbol ref
+);
+
+self_types(
+ int typeName: @symbol ref,
+ int selfType: @type_reference ref
+);
+
+tuple_type_min_length(
+ unique int typ: @type ref,
+ int minLength: int ref
+);
+
+tuple_type_rest_index(
+ unique int typ: @type ref,
+ int index: int ref
+);
+
+// comments
+comments (unique int id: @comment,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(900) tostring: string ref);
+
+case @comment.kind of
+ 0 = @slashslash_comment
+| 1 = @slashstar_comment
+| 2 = @doc_comment
+| 3 = @html_comment_start
+| 4 = @htmlcommentend;
+
+@html_comment = @html_comment_start | @htmlcommentend;
+@line_comment = @slashslash_comment | @html_comment;
+@block_comment = @slashstar_comment | @doc_comment;
+
+// source lines
+lines (unique int id: @line,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(2) terminator: string ref);
+indentation (int file: @file ref,
+ int lineno: int ref,
+ varchar(1) indentChar: string ref,
+ int indentDepth: int ref);
+
+// JavaScript parse errors
+js_parse_errors (unique int id: @js_parse_error,
+ int toplevel: @toplevel ref,
+ varchar(900) message: string ref,
+ varchar(900) line: string ref);
+
+// regular expressions
+#keyset[parent, idx]
+regexpterm (unique int id: @regexpterm,
+ int kind: int ref,
+ int parent: @regexpparent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr;
+
+case @regexpterm.kind of
+ 0 = @regexp_alt
+| 1 = @regexp_seq
+| 2 = @regexp_caret
+| 3 = @regexp_dollar
+| 4 = @regexp_wordboundary
+| 5 = @regexp_nonwordboundary
+| 6 = @regexp_positive_lookahead
+| 7 = @regexp_negative_lookahead
+| 8 = @regexp_star
+| 9 = @regexp_plus
+| 10 = @regexp_opt
+| 11 = @regexp_range
+| 12 = @regexp_dot
+| 13 = @regexp_group
+| 14 = @regexp_normal_constant
+| 15 = @regexp_hex_escape
+| 16 = @regexp_unicode_escape
+| 17 = @regexp_dec_escape
+| 18 = @regexp_oct_escape
+| 19 = @regexp_ctrl_escape
+| 20 = @regexp_char_class_escape
+| 21 = @regexp_id_escape
+| 22 = @regexp_backref
+| 23 = @regexp_char_class
+| 24 = @regexp_char_range
+| 25 = @regexp_positive_lookbehind
+| 26 = @regexp_negative_lookbehind
+| 27 = @regexp_unicode_property_escape;
+
+regexp_parse_errors (unique int id: @regexp_parse_error,
+ int regexp: @regexpterm ref,
+ varchar(900) message: string ref);
+
+@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
+@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape;
+@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
+@regexp_constant = @regexp_normal_constant | @regexp_char_escape;
+@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead;
+@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind;
+@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind;
+@regexp_anchor = @regexp_dollar | @regexp_caret;
+
+is_greedy (int id: @regexp_quantifier ref);
+range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref);
+range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref);
+is_capture (unique int id: @regexp_group ref, int number: int ref);
+is_named_capture (unique int id: @regexp_group ref, string name: string ref);
+is_inverted (int id: @regexp_char_class ref);
+regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref);
+char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
+backref (unique int id: @regexp_backref ref, int value: int ref);
+named_backref (unique int id: @regexp_backref ref, string name: string ref);
+unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref);
+unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref);
+
+// tokens
+#keyset[toplevel, idx]
+tokeninfo (unique int id: @token,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ int idx: int ref,
+ varchar(900) value: string ref);
+
+case @token.kind of
+ 0 = @token_eof
+| 1 = @token_null_literal
+| 2 = @token_boolean_literal
+| 3 = @token_numeric_literal
+| 4 = @token_string_literal
+| 5 = @token_regular_expression
+| 6 = @token_identifier
+| 7 = @token_keyword
+| 8 = @token_punctuator;
+
+// associate comments with the token immediately following them (which may be EOF)
+next_token (int comment: @comment ref, int token: @token ref);
+
+// JSON
+#keyset[parent, idx]
+json (unique int id: @json_value,
+ int kind: int ref,
+ int parent: @json_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+json_literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @json_value ref);
+
+json_properties (int obj: @json_object ref,
+ varchar(900) property: string ref,
+ int value: @json_value ref);
+
+json_errors (unique int id: @json_parse_error,
+ varchar(900) message: string ref);
+
+json_locations(unique int locatable: @json_locatable ref,
+ int location: @location_default ref);
+
+case @json_value.kind of
+ 0 = @json_null
+| 1 = @json_boolean
+| 2 = @json_number
+| 3 = @json_string
+| 4 = @json_array
+| 5 = @json_object;
+
+@json_parent = @json_object | @json_array | @file;
+
+@json_locatable = @json_value | @json_parse_error;
+
+// locations
+@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr;
+
+@locatable = @file
+ | @ast_node
+ | @comment
+ | @line
+ | @js_parse_error | @regexp_parse_error
+ | @regexpterm
+ | @json_locatable
+ | @token
+ | @cfg_node
+ | @jsdoc | @jsdoc_type_expr | @jsdoc_tag
+ | @yaml_locatable
+ | @xmllocatable
+ | @configLocatable
+ | @template_placeholder_tag;
+
+hasLocation (unique int locatable: @locatable ref,
+ int location: @location ref);
+
+// CFG
+entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref);
+exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref);
+guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref);
+case @guard_node.kind of
+ 0 = @falsy_guard
+| 1 = @truthy_guard;
+@condition_guard = @falsy_guard | @truthy_guard;
+
+@synthetic_cfg_node = @entry_node | @exit_node | @guard_node;
+@cfg_node = @synthetic_cfg_node | @expr_parent;
+
+successor (int pred: @cfg_node ref, int succ: @cfg_node ref);
+
+// JSDoc comments
+jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref);
+#keyset[parent, idx]
+jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref,
+ int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref);
+jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+
+#keyset[parent, idx]
+jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
+ int kind: int ref,
+ int parent: @jsdoc_type_expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+case @jsdoc_type_expr.kind of
+ 0 = @jsdoc_any_type_expr
+| 1 = @jsdoc_null_type_expr
+| 2 = @jsdoc_undefined_type_expr
+| 3 = @jsdoc_unknown_type_expr
+| 4 = @jsdoc_void_type_expr
+| 5 = @jsdoc_named_type_expr
+| 6 = @jsdoc_applied_type_expr
+| 7 = @jsdoc_nullable_type_expr
+| 8 = @jsdoc_non_nullable_type_expr
+| 9 = @jsdoc_record_type_expr
+| 10 = @jsdoc_array_type_expr
+| 11 = @jsdoc_union_type_expr
+| 12 = @jsdoc_function_type_expr
+| 13 = @jsdoc_optional_type_expr
+| 14 = @jsdoc_rest_type_expr
+;
+
+#keyset[id, idx]
+jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref);
+jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref);
+jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref);
+
+@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag;
+
+jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref);
+
+@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property;
+
+@optionalchainable = @call_expr | @propaccess;
+
+isOptionalChaining(int id: @optionalchainable ref);
+
+/**
+ * The time taken for the extraction of a file.
+ * This table contains non-deterministic content.
+ *
+ * The sum of the `time` column for each (`file`, `timerKind`) pair
+ * is the total time taken for extraction of `file`. The `extractionPhase`
+ * column provides a granular view of the extraction time of the file.
+ */
+extraction_time(
+ int file : @file ref,
+ // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`.
+ int extractionPhase: int ref,
+ // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds
+ int timerKind: int ref,
+ float time: float ref
+)
+
+/**
+* Non-timing related data for the extraction of a single file.
+* This table contains non-deterministic content.
+*/
+extraction_data(
+ int file : @file ref,
+ // the absolute path to the cache file
+ varchar(900) cacheFile: string ref,
+ boolean fromCache: boolean ref,
+ int length: int ref
+)
+
+/*- YAML -*/
+
+#keyset[parent, idx]
+yaml (unique int id: @yaml_node,
+ int kind: int ref,
+ int parent: @yaml_node_parent ref,
+ int idx: int ref,
+ string tag: string ref,
+ string tostring: string ref);
+
+case @yaml_node.kind of
+ 0 = @yaml_scalar_node
+| 1 = @yaml_mapping_node
+| 2 = @yaml_sequence_node
+| 3 = @yaml_alias_node
+;
+
+@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node;
+
+@yaml_node_parent = @yaml_collection_node | @file;
+
+yaml_anchors (unique int node: @yaml_node ref,
+ string anchor: string ref);
+
+yaml_aliases (unique int alias: @yaml_alias_node ref,
+ string target: string ref);
+
+yaml_scalars (unique int scalar: @yaml_scalar_node ref,
+ int style: int ref,
+ string value: string ref);
+
+yaml_errors (unique int id: @yaml_error,
+ string message: string ref);
+
+yaml_locations(unique int locatable: @yaml_locatable ref,
+ int location: @location_default ref);
+
+@yaml_locatable = @yaml_node | @yaml_error;
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*- Configuration files with key value pairs -*/
+
+configs(
+ unique int id: @config
+);
+
+configNames(
+ unique int id: @configName,
+ int config: @config ref,
+ string name: string ref
+);
+
+configValues(
+ unique int id: @configValue,
+ int config: @config ref,
+ string value: string ref
+);
+
+configLocations(
+ int locatable: @configLocatable ref,
+ int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties
new file mode 100644
index 00000000000..e4f4275eac4
--- /dev/null
+++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties
@@ -0,0 +1,2 @@
+description: Add @using_decl_stmt
+compatibility: backwards
diff --git a/javascript/extractor/lib/typescript/package-lock.json b/javascript/extractor/lib/typescript/package-lock.json
new file mode 100644
index 00000000000..9384d286b79
--- /dev/null
+++ b/javascript/extractor/lib/typescript/package-lock.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-parser-wrapper",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "typescript-parser-wrapper",
+ "dependencies": {
+ "typescript": "5.2.2"
+ },
+ "devDependencies": {
+ "@types/node": "18.15.3"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "18.15.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz",
+ "integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ }
+ }
+}
diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json
index 3190b683d34..e043afa01db 100644
--- a/javascript/extractor/lib/typescript/package.json
+++ b/javascript/extractor/lib/typescript/package.json
@@ -2,7 +2,7 @@
"name": "typescript-parser-wrapper",
"private": true,
"dependencies": {
- "typescript": "5.1.3"
+ "typescript": "5.2.2"
},
"scripts": {
"build": "tsc --project tsconfig.json",
diff --git a/javascript/extractor/lib/typescript/src/main.ts b/javascript/extractor/lib/typescript/src/main.ts
index 2594f4e35f5..e9849f42f5c 100644
--- a/javascript/extractor/lib/typescript/src/main.ts
+++ b/javascript/extractor/lib/typescript/src/main.ts
@@ -361,7 +361,10 @@ function handleParseCommand(command: ParseCommand, checkPending = true) {
let filename = command.filename;
let expectedFilename = state.pendingFiles[state.pendingFileIndex];
if (expectedFilename !== filename && checkPending) {
- throw new Error("File requested out of order. Expected '" + expectedFilename + "' but got '" + filename + "'");
+ // File was requested out of order. This happens in rare cases because the Java process decided against extracting it,
+ // for example because it was too large. Just recover and accept that some work was wasted.
+ state.pendingResponse = null;
+ state.pendingFileIndex = state.pendingFiles.indexOf(filename);
}
++state.pendingFileIndex;
let response = state.pendingResponse || extractFile(command.filename);
diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock
index 355c257cf69..d72f714a4fb 100644
--- a/javascript/extractor/lib/typescript/yarn.lock
+++ b/javascript/extractor/lib/typescript/yarn.lock
@@ -4,10 +4,10 @@
"@types/node@18.15.3":
version "18.15.3"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014"
+ resolved "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz"
integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==
-typescript@5.1.3:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826"
- integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==
+typescript@5.2.2:
+ version "5.2.2"
+ resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz"
+ integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java
index aac1c425e77..b7325021b72 100644
--- a/javascript/extractor/src/com/semmle/jcorn/Parser.java
+++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java
@@ -2674,17 +2674,42 @@ public class Parser {
// - 'async /*foo*/ function' is OK.
// - 'async /*\n*/ function' is invalid.
boolean isAsyncFunction() {
+ return isAsyncKeyword("async", "function");
+ }
+
+ boolean isAwaitUsing() {
+ return isAsyncKeyword("await", "using");
+ }
+
+ // check 'pre [no LineTerminator here] keyword'
+ // e.g. `await using" or `async function`.
+ // is only used for async/await parsing, so it requires ecmaVersion >= 8.
+ boolean isAsyncKeyword(String pre, String keyword) {
if (this.type != TokenType.name
|| this.options.ecmaVersion() < 8
- || !this.value.equals("async")) return false;
+ || !this.value.equals(pre)) return false;
+
+ Matcher m = Whitespace.skipWhiteSpace.matcher(this.input);
+ m.find(this.pos);
+ int next = m.end();
+ int len = keyword.length();
+ return !Whitespace.lineBreakG.matcher(inputSubstring(this.pos, next)).matches()
+ && inputSubstring(next, next + len).equals(keyword)
+ && (next + len == this.input.length()
+ || !Identifiers.isIdentifierChar(this.input.codePointAt(next + len), false));
+ }
+
+ // matches "using [identifier]"
+ boolean isUsingDecl() {
+ if (this.type != TokenType.name
+ || this.options.ecmaVersion() < 8
+ || !this.value.equals("using")) return false;
Matcher m = Whitespace.skipWhiteSpace.matcher(this.input);
m.find(this.pos);
int next = m.end();
return !Whitespace.lineBreakG.matcher(inputSubstring(this.pos, next)).matches()
- && inputSubstring(next, next + 8).equals("function")
- && (next + 8 == this.input.length()
- || !Identifiers.isIdentifierChar(this.input.codePointAt(next + 8), false));
+ && Identifiers.isIdentifierChar(this.input.codePointAt(next), false);
}
/**
@@ -2737,7 +2762,7 @@ public class Parser {
return this.parseThrowStatement(startLoc);
} else if (starttype == TokenType._try) {
return this.parseTryStatement(startLoc);
- } else if (starttype == TokenType._const || starttype == TokenType._var) {
+ } else if (starttype == TokenType._const || starttype == TokenType._var || this.isUsingDecl()) {
if (kind == null) kind = String.valueOf(this.value);
if (!declaration && !kind.equals("var")) this.unexpected();
return this.parseVarStatement(startLoc, kind);
@@ -2761,6 +2786,10 @@ public class Parser {
: this.parseExport(startLoc, exports);
} else {
+ if (this.isAwaitUsing() && (this.inAsync || options.esnext() && !this.inFunction)) {
+ this.next();
+ return this.parseVarStatement(startLoc, "using");
+ }
if (this.isAsyncFunction() && declaration) {
this.next();
return this.parseFunctionStatement(startLoc, true);
@@ -2840,7 +2869,10 @@ public class Parser {
this.expect(TokenType.parenL);
if (this.type == TokenType.semi) return this.parseFor(startLoc, null);
boolean isLet = this.isLet();
- if (this.type == TokenType._var || this.type == TokenType._const || isLet) {
+ if (this.isAwaitUsing() && this.inAsync) {
+ this.next(); // just skip the await and treat it as a `using` statement
+ }
+ if (this.type == TokenType._var || this.type == TokenType._const || isLet || (this.type == TokenType.name && this.value.equals("using"))) {
Position initStartLoc = this.startLoc;
String kind = isLet ? "let" : String.valueOf(this.value);
this.next();
@@ -3122,7 +3154,7 @@ public class Parser {
Expression init = null;
if (this.eat(TokenType.eq)) {
init = this.parseMaybeAssign(isFor, null, null);
- } else if (kind.equals("const")
+ } else if ((kind.equals("const") || kind.equals("using"))
&& !(this.type == TokenType._in
|| (this.options.ecmaVersion() >= 6 && this.isContextual("of")))) {
this.raiseRecoverable(
diff --git a/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java b/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java
index ffe5d13b296..b86d8e8e0e2 100644
--- a/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java
+++ b/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java
@@ -28,8 +28,8 @@ public class VariableDeclaration extends Statement {
}
/**
- * The kind of this variable declaration statement; one of "var", "let"
- * or "const".
+ * The kind of this variable declaration statement; one of "var", "let",
+ * "const", or "using".
*/
public String getKind() {
return kind;
@@ -42,6 +42,7 @@ public class VariableDeclaration extends Statement {
*/
public boolean isBlockScoped(ECMAVersion ecmaVersion) {
return "let".equals(kind)
+ || "using".equals(kind)
|| ecmaVersion.compareTo(ECMAVersion.ECMA2015) >= 0 && "const".equals(kind);
}
diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java
index 2a188676924..72156e94927 100644
--- a/javascript/extractor/src/com/semmle/js/extractor/Main.java
+++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java
@@ -41,7 +41,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
- public static final String EXTRACTOR_VERSION = "2023-04-19";
+ public static final String EXTRACTOR_VERSION = "2023-08-10";
public static final Pattern NEWLINE = Pattern.compile("\n");
diff --git a/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java b/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java
index db9982ba152..b4e540c3a0b 100644
--- a/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java
+++ b/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java
@@ -58,6 +58,7 @@ public class StmtKinds {
declKinds.put("var", 18);
declKinds.put("const", 22);
declKinds.put("let", 23);
+ declKinds.put("using", 40);
}
public static int getStmtKind(final Statement stmt) {
diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java
index 7b68106bb3f..bf48c3fd7c9 100644
--- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java
+++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java
@@ -2683,10 +2683,13 @@ public class TypeScriptASTConverter {
}
/**
- * Gets the declaration kind of the given node, which is one of {@code "var"}, {@code "let"} or
- * {@code "const"}.
+ * Gets the declaration kind of the given node, which is one of {@code "var"}, {@code "let"},
+ * {@code "const"}, or {@code "using"}.
*/
private String getDeclarationKind(JsonObject declarationList) {
+ if (hasFlag(declarationList, "Using")) {
+ return "using";
+ }
return declarationList.get("$declarationKind").getAsString();
}
}
diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md
index ad0301e9c7b..13a56f3dcda 100644
--- a/javascript/ql/lib/CHANGELOG.md
+++ b/javascript/ql/lib/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.7.4
+
+### Major Analysis Improvements
+
+* Added support for TypeScript 5.2.
+
## 0.7.3
No user-facing changes.
diff --git a/javascript/ql/lib/change-notes/released/0.7.4.md b/javascript/ql/lib/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..7608c571bdf
--- /dev/null
+++ b/javascript/ql/lib/change-notes/released/0.7.4.md
@@ -0,0 +1,5 @@
+## 0.7.4
+
+### Major Analysis Improvements
+
+* Added support for TypeScript 5.2.
diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/javascript/ql/lib/codeql-pack.release.yml
+++ b/javascript/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml
index d65eefd366c..bb8abe793e6 100644
--- a/javascript/ql/lib/qlpack.yml
+++ b/javascript/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/javascript-all
-version: 0.7.4-dev
+version: 0.7.4
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript
diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll
index 0defda1dc6b..2d3e0d26074 100644
--- a/javascript/ql/lib/semmle/javascript/PrintAst.qll
+++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll
@@ -246,13 +246,15 @@ private module PrintJavaScript {
}
/**
- * Gets "var" or "const" or "let" depending on what type of declaration `decl` is.
+ * Gets "var" or "const" or "let" or "using" depending on what type of declaration `decl` is.
*/
private string getDeclarationKeyword(DeclStmt decl) {
decl instanceof VarDeclStmt and result = "var"
or
decl instanceof ConstDeclStmt and result = "const"
or
+ decl instanceof UsingDeclStmt and result = "using"
+ or
decl instanceof LetStmt and result = "let"
}
}
diff --git a/javascript/ql/lib/semmle/javascript/Stmt.qll b/javascript/ql/lib/semmle/javascript/Stmt.qll
index 24a901a0dcc..ae59c0b81eb 100644
--- a/javascript/ql/lib/semmle/javascript/Stmt.qll
+++ b/javascript/ql/lib/semmle/javascript/Stmt.qll
@@ -1041,6 +1041,17 @@ class VarDeclStmt extends @var_decl_stmt, DeclStmt { }
*/
class ConstDeclStmt extends @const_decl_stmt, DeclStmt { }
+/**
+ * A `using` declaration statement.
+ *
+ * Example:
+ *
+ * ```
+ * using file = new TextFile("file.txt");
+ * ```
+ */
+class UsingDeclStmt extends @using_decl_stmt, DeclStmt { }
+
/**
* A `let` declaration statement.
*
diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme b/javascript/ql/lib/semmlecode.javascript.dbscheme
index 8accf0f930b..c88c69174bd 100644
--- a/javascript/ql/lib/semmlecode.javascript.dbscheme
+++ b/javascript/ql/lib/semmlecode.javascript.dbscheme
@@ -162,9 +162,10 @@ case @stmt.kind of
| 37 = @external_module_declaration
| 38 = @export_as_namespace_declaration
| 39 = @global_augmentation_declaration
+| 40 = @using_decl_stmt
;
-@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt;
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt;
@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration;
diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats
index c198daf9e67..97ba6f9bcc3 100644
--- a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats
+++ b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats
@@ -170,6 +170,10 @@
5
+@using_decl_stmt
+5
+
+
@export_default_declaration
5
diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme
new file mode 100644
index 00000000000..8accf0f930b
--- /dev/null
+++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme
@@ -0,0 +1,1189 @@
+/*** Standard fragments ***/
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- JavaScript-specific part -*/
+
+@location = @location_default
+
+@sourceline = @locatable;
+
+filetype(
+ int file: @file ref,
+ string filetype: string ref
+)
+
+// top-level code fragments
+toplevels (unique int id: @toplevel,
+ int kind: int ref);
+
+is_externs (int toplevel: @toplevel ref);
+
+case @toplevel.kind of
+ 0 = @script
+| 1 = @inline_script
+| 2 = @event_handler
+| 3 = @javascript_url
+| 4 = @template_toplevel;
+
+is_module (int tl: @toplevel ref);
+is_nodejs (int tl: @toplevel ref);
+is_es2015_module (int tl: @toplevel ref);
+is_closure_module (int tl: @toplevel ref);
+
+@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag;
+toplevel_parent_xml_node(
+ unique int toplevel: @toplevel ref,
+ int xmlnode: @xml_node_with_code ref);
+
+xml_element_parent_expression(
+ unique int xmlnode: @xmlelement ref,
+ int expression: @expr ref,
+ int index: int ref);
+
+// statements
+#keyset[parent, idx]
+stmts (unique int id: @stmt,
+ int kind: int ref,
+ int parent: @stmt_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+stmt_containers (unique int stmt: @stmt ref,
+ int container: @stmt_container ref);
+
+jump_targets (unique int jump: @stmt ref,
+ int target: @stmt ref);
+
+@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer;
+@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration;
+
+case @stmt.kind of
+ 0 = @empty_stmt
+| 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @labeled_stmt
+| 5 = @break_stmt
+| 6 = @continue_stmt
+| 7 = @with_stmt
+| 8 = @switch_stmt
+| 9 = @return_stmt
+| 10 = @throw_stmt
+| 11 = @try_stmt
+| 12 = @while_stmt
+| 13 = @do_while_stmt
+| 14 = @for_stmt
+| 15 = @for_in_stmt
+| 16 = @debugger_stmt
+| 17 = @function_decl_stmt
+| 18 = @var_decl_stmt
+| 19 = @case
+| 20 = @catch_clause
+| 21 = @for_of_stmt
+| 22 = @const_decl_stmt
+| 23 = @let_stmt
+| 24 = @legacy_let_stmt
+| 25 = @for_each_stmt
+| 26 = @class_decl_stmt
+| 27 = @import_declaration
+| 28 = @export_all_declaration
+| 29 = @export_default_declaration
+| 30 = @export_named_declaration
+| 31 = @namespace_declaration
+| 32 = @import_equals_declaration
+| 33 = @export_assign_declaration
+| 34 = @interface_declaration
+| 35 = @type_alias_declaration
+| 36 = @enum_declaration
+| 37 = @external_module_declaration
+| 38 = @export_as_namespace_declaration
+| 39 = @global_augmentation_declaration
+;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt;
+
+@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration;
+
+@namespace_definition = @namespace_declaration | @enum_declaration;
+@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member;
+
+is_instantiated(unique int decl: @namespace_declaration ref);
+
+@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field;
+has_declare_keyword(unique int stmt: @declarable_node ref);
+
+is_for_await_of(unique int forof: @for_of_stmt ref);
+
+// expressions
+#keyset[parent, idx]
+exprs (unique int id: @expr,
+ int kind: int ref,
+ int parent: @expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @expr_or_type ref);
+
+enclosing_stmt (unique int expr: @expr_or_type ref,
+ int stmt: @stmt ref);
+
+expr_containers (unique int expr: @expr_or_type ref,
+ int container: @stmt_container ref);
+
+array_size (unique int ae: @arraylike ref,
+ int sz: int ref);
+
+is_delegating (int yield: @yield_expr ref);
+
+@expr_or_stmt = @expr | @stmt;
+@expr_or_type = @expr | @typeexpr;
+@expr_parent = @expr_or_stmt | @property | @function_typeexpr;
+@arraylike = @array_expr | @array_pattern;
+@type_annotation = @typeexpr | @jsdoc_type_expr;
+@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel;
+
+case @expr.kind of
+ 0 = @label
+| 1 = @null_literal
+| 2 = @boolean_literal
+| 3 = @number_literal
+| 4 = @string_literal
+| 5 = @regexp_literal
+| 6 = @this_expr
+| 7 = @array_expr
+| 8 = @obj_expr
+| 9 = @function_expr
+| 10 = @seq_expr
+| 11 = @conditional_expr
+| 12 = @new_expr
+| 13 = @call_expr
+| 14 = @dot_expr
+| 15 = @index_expr
+| 16 = @neg_expr
+| 17 = @plus_expr
+| 18 = @log_not_expr
+| 19 = @bit_not_expr
+| 20 = @typeof_expr
+| 21 = @void_expr
+| 22 = @delete_expr
+| 23 = @eq_expr
+| 24 = @neq_expr
+| 25 = @eqq_expr
+| 26 = @neqq_expr
+| 27 = @lt_expr
+| 28 = @le_expr
+| 29 = @gt_expr
+| 30 = @ge_expr
+| 31 = @lshift_expr
+| 32 = @rshift_expr
+| 33 = @urshift_expr
+| 34 = @add_expr
+| 35 = @sub_expr
+| 36 = @mul_expr
+| 37 = @div_expr
+| 38 = @mod_expr
+| 39 = @bitor_expr
+| 40 = @xor_expr
+| 41 = @bitand_expr
+| 42 = @in_expr
+| 43 = @instanceof_expr
+| 44 = @logand_expr
+| 45 = @logor_expr
+| 47 = @assign_expr
+| 48 = @assign_add_expr
+| 49 = @assign_sub_expr
+| 50 = @assign_mul_expr
+| 51 = @assign_div_expr
+| 52 = @assign_mod_expr
+| 53 = @assign_lshift_expr
+| 54 = @assign_rshift_expr
+| 55 = @assign_urshift_expr
+| 56 = @assign_or_expr
+| 57 = @assign_xor_expr
+| 58 = @assign_and_expr
+| 59 = @preinc_expr
+| 60 = @postinc_expr
+| 61 = @predec_expr
+| 62 = @postdec_expr
+| 63 = @par_expr
+| 64 = @var_declarator
+| 65 = @arrow_function_expr
+| 66 = @spread_element
+| 67 = @array_pattern
+| 68 = @object_pattern
+| 69 = @yield_expr
+| 70 = @tagged_template_expr
+| 71 = @template_literal
+| 72 = @template_element
+| 73 = @array_comprehension_expr
+| 74 = @generator_expr
+| 75 = @for_in_comprehension_block
+| 76 = @for_of_comprehension_block
+| 77 = @legacy_letexpr
+| 78 = @var_decl
+| 79 = @proper_varaccess
+| 80 = @class_expr
+| 81 = @super_expr
+| 82 = @newtarget_expr
+| 83 = @named_import_specifier
+| 84 = @import_default_specifier
+| 85 = @import_namespace_specifier
+| 86 = @named_export_specifier
+| 87 = @exp_expr
+| 88 = @assign_exp_expr
+| 89 = @jsx_element
+| 90 = @jsx_qualified_name
+| 91 = @jsx_empty_expr
+| 92 = @await_expr
+| 93 = @function_sent_expr
+| 94 = @decorator
+| 95 = @export_default_specifier
+| 96 = @export_namespace_specifier
+| 97 = @bind_expr
+| 98 = @external_module_reference
+| 99 = @dynamic_import
+| 100 = @expression_with_type_arguments
+| 101 = @prefix_type_assertion
+| 102 = @as_type_assertion
+| 103 = @export_varaccess
+| 104 = @decorator_list
+| 105 = @non_null_assertion
+| 106 = @bigint_literal
+| 107 = @nullishcoalescing_expr
+| 108 = @e4x_xml_anyname
+| 109 = @e4x_xml_static_attribute_selector
+| 110 = @e4x_xml_dynamic_attribute_selector
+| 111 = @e4x_xml_filter_expression
+| 112 = @e4x_xml_static_qualident
+| 113 = @e4x_xml_dynamic_qualident
+| 114 = @e4x_xml_dotdotexpr
+| 115 = @import_meta_expr
+| 116 = @assignlogandexpr
+| 117 = @assignlogorexpr
+| 118 = @assignnullishcoalescingexpr
+| 119 = @template_pipe_ref
+| 120 = @generated_code_expr
+| 121 = @satisfies_expr
+;
+
+@varaccess = @proper_varaccess | @export_varaccess;
+@varref = @var_decl | @varaccess;
+
+@identifier = @label | @varref | @type_identifier;
+
+@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal;
+
+@propaccess = @dot_expr | @index_expr;
+
+@invokeexpr = @new_expr | @call_expr;
+
+@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element;
+
+@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr;
+
+@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr;
+
+@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr;
+
+@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr;
+
+@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr;
+
+@pattern = @varref | @array_pattern | @object_pattern;
+
+@comprehension_expr = @array_comprehension_expr | @generator_expr;
+
+@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block;
+
+@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier;
+
+@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier;
+
+@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier;
+
+@type_assertion = @as_type_assertion | @prefix_type_assertion;
+
+@class_definition = @class_decl_stmt | @class_expr;
+@interface_definition = @interface_declaration | @interface_typeexpr;
+@class_or_interface = @class_definition | @interface_definition;
+
+@lexical_decl = @var_decl | @type_decl;
+@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access;
+@lexical_ref = @lexical_decl | @lexical_access;
+
+@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector;
+@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident;
+
+expr_contains_template_tag_location(
+ int expr: @expr ref,
+ int location: @location ref
+);
+
+@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file;
+
+template_placeholder_tag_info(
+ unique int node: @template_placeholder_tag,
+ int parentNode: @template_placeholder_tag_parent ref,
+ varchar(900) raw: string ref
+);
+
+// scopes
+scopes (unique int id: @scope,
+ int kind: int ref);
+
+case @scope.kind of
+ 0 = @global_scope
+| 1 = @function_scope
+| 2 = @catch_scope
+| 3 = @module_scope
+| 4 = @block_scope
+| 5 = @for_scope
+| 6 = @for_in_scope // for-of scopes work the same as for-in scopes
+| 7 = @comprehension_block_scope
+| 8 = @class_expr_scope
+| 9 = @namespace_scope
+| 10 = @class_decl_scope
+| 11 = @interface_scope
+| 12 = @type_alias_scope
+| 13 = @mapped_type_scope
+| 14 = @enum_scope
+| 15 = @external_module_scope
+| 16 = @conditional_type_scope;
+
+scopenodes (unique int node: @ast_node ref,
+ int scope: @scope ref);
+
+scopenesting (unique int inner: @scope ref,
+ int outer: @scope ref);
+
+// functions
+@function = @function_decl_stmt | @function_expr | @arrow_function_expr;
+
+@parameterized = @function | @catch_clause;
+@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr;
+
+is_generator (int fun: @function ref);
+has_rest_parameter (int fun: @function ref);
+is_async (int fun: @function ref);
+
+// variables and lexically scoped type names
+#keyset[scope, name]
+variables (unique int id: @variable,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_type_names (unique int id: @local_type_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_namespace_names (unique int id: @local_namespace_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+is_arguments_object (int id: @variable ref);
+
+@lexical_name = @variable | @local_type_name | @local_namespace_name;
+
+@bind_id = @varaccess | @local_var_type_access;
+bind (unique int id: @bind_id ref,
+ int decl: @variable ref);
+
+decl (unique int id: @var_decl ref,
+ int decl: @variable ref);
+
+@typebind_id = @local_type_access | @export_varaccess;
+typebind (unique int id: @typebind_id ref,
+ int decl: @local_type_name ref);
+
+@typedecl_id = @type_decl | @var_decl;
+typedecl (unique int id: @typedecl_id ref,
+ int decl: @local_type_name ref);
+
+namespacedecl (unique int id: @var_decl ref,
+ int decl: @local_namespace_name ref);
+
+@namespacebind_id = @local_namespace_access | @export_varaccess;
+namespacebind (unique int id: @namespacebind_id ref,
+ int decl: @local_namespace_name ref);
+
+
+// properties in object literals, property patterns in object patterns, and method declarations in classes
+#keyset[parent, index]
+properties (unique int id: @property,
+ int parent: @property_parent ref,
+ int index: int ref,
+ int kind: int ref,
+ varchar(900) tostring: string ref);
+
+case @property.kind of
+ 0 = @value_property
+| 1 = @property_getter
+| 2 = @property_setter
+| 3 = @jsx_attribute
+| 4 = @function_call_signature
+| 5 = @constructor_call_signature
+| 6 = @index_signature
+| 7 = @enum_member
+| 8 = @proper_field
+| 9 = @parameter_field
+| 10 = @static_initializer
+;
+
+@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration;
+@property_accessor = @property_getter | @property_setter;
+@call_signature = @function_call_signature | @constructor_call_signature;
+@field = @proper_field | @parameter_field;
+@field_or_vardeclarator = @field | @var_declarator;
+
+is_computed (int id: @property ref);
+is_method (int id: @property ref);
+is_static (int id: @property ref);
+is_abstract_member (int id: @property ref);
+is_const_enum (int id: @enum_declaration ref);
+is_abstract_class (int id: @class_decl_stmt ref);
+
+has_public_keyword (int id: @property ref);
+has_private_keyword (int id: @property ref);
+has_protected_keyword (int id: @property ref);
+has_readonly_keyword (int id: @property ref);
+has_type_keyword (int id: @type_keyword_operand ref);
+is_optional_member (int id: @property ref);
+has_definite_assignment_assertion (int id: @field_or_vardeclarator ref);
+is_optional_parameter_declaration (unique int parameter: @pattern ref);
+
+#keyset[constructor, param_index]
+parameter_fields(
+ unique int field: @parameter_field ref,
+ int constructor: @function_expr ref,
+ int param_index: int ref
+);
+
+// types
+#keyset[parent, idx]
+typeexprs (
+ unique int id: @typeexpr,
+ int kind: int ref,
+ int parent: @typeexpr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref
+);
+
+case @typeexpr.kind of
+ 0 = @local_type_access
+| 1 = @type_decl
+| 2 = @keyword_typeexpr
+| 3 = @string_literal_typeexpr
+| 4 = @number_literal_typeexpr
+| 5 = @boolean_literal_typeexpr
+| 6 = @array_typeexpr
+| 7 = @union_typeexpr
+| 8 = @indexed_access_typeexpr
+| 9 = @intersection_typeexpr
+| 10 = @parenthesized_typeexpr
+| 11 = @tuple_typeexpr
+| 12 = @keyof_typeexpr
+| 13 = @qualified_type_access
+| 14 = @generic_typeexpr
+| 15 = @type_label
+| 16 = @typeof_typeexpr
+| 17 = @local_var_type_access
+| 18 = @qualified_var_type_access
+| 19 = @this_var_type_access
+| 20 = @predicate_typeexpr
+| 21 = @interface_typeexpr
+| 22 = @type_parameter
+| 23 = @plain_function_typeexpr
+| 24 = @constructor_typeexpr
+| 25 = @local_namespace_access
+| 26 = @qualified_namespace_access
+| 27 = @mapped_typeexpr
+| 28 = @conditional_typeexpr
+| 29 = @infer_typeexpr
+| 30 = @import_type_access
+| 31 = @import_namespace_access
+| 32 = @import_var_type_access
+| 33 = @optional_typeexpr
+| 34 = @rest_typeexpr
+| 35 = @bigint_literal_typeexpr
+| 36 = @readonly_typeexpr
+| 37 = @template_literal_typeexpr
+;
+
+@typeref = @typeaccess | @type_decl;
+@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access;
+@typeexpr_parent = @expr | @stmt | @property | @typeexpr;
+@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr;
+@typeaccess = @local_type_access | @qualified_type_access | @import_type_access;
+@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access;
+@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access;
+@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access;
+
+@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr;
+
+// types
+types (
+ unique int id: @type,
+ int kind: int ref,
+ varchar(900) tostring: string ref
+);
+
+#keyset[parent, idx]
+type_child (
+ int child: @type ref,
+ int parent: @type ref,
+ int idx: int ref
+);
+
+case @type.kind of
+ 0 = @any_type
+| 1 = @string_type
+| 2 = @number_type
+| 3 = @union_type
+| 4 = @true_type
+| 5 = @false_type
+| 6 = @type_reference
+| 7 = @object_type
+| 8 = @canonical_type_variable_type
+| 9 = @typeof_type
+| 10 = @void_type
+| 11 = @undefined_type
+| 12 = @null_type
+| 13 = @never_type
+| 14 = @plain_symbol_type
+| 15 = @unique_symbol_type
+| 16 = @objectkeyword_type
+| 17 = @intersection_type
+| 18 = @tuple_type
+| 19 = @lexical_type_variable_type
+| 20 = @this_type
+| 21 = @number_literal_type
+| 22 = @string_literal_type
+| 23 = @unknown_type
+| 24 = @bigint_type
+| 25 = @bigint_literal_type
+;
+
+@boolean_literal_type = @true_type | @false_type;
+@symbol_type = @plain_symbol_type | @unique_symbol_type;
+@union_or_intersection_type = @union_type | @intersection_type;
+@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type;
+
+has_asserts_keyword(int node: @predicate_typeexpr ref);
+
+@typed_ast_node = @expr | @typeexpr | @function;
+ast_node_type(
+ unique int node: @typed_ast_node ref,
+ int typ: @type ref);
+
+declared_function_signature(
+ unique int node: @function ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_signature(
+ unique int node: @invokeexpr ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_overload_index(
+ unique int node: @invokeexpr ref,
+ int index: int ref
+);
+
+symbols (
+ unique int id: @symbol,
+ int kind: int ref,
+ varchar(900) name: string ref
+);
+
+symbol_parent (
+ unique int symbol: @symbol ref,
+ int parent: @symbol ref
+);
+
+symbol_module (
+ int symbol: @symbol ref,
+ varchar(900) moduleName: string ref
+);
+
+symbol_global (
+ int symbol: @symbol ref,
+ varchar(900) globalName: string ref
+);
+
+case @symbol.kind of
+ 0 = @root_symbol
+| 1 = @member_symbol
+| 2 = @other_symbol
+;
+
+@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type;
+@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration;
+
+ast_node_symbol(
+ unique int node: @ast_node_with_symbol ref,
+ int symbol: @symbol ref);
+
+type_symbol(
+ unique int typ: @type_with_symbol ref,
+ int symbol: @symbol ref);
+
+#keyset[typ, name]
+type_property(
+ int typ: @type ref,
+ varchar(900) name: string ref,
+ int propertyType: @type ref);
+
+type_alias(
+ unique int aliasType: @type ref,
+ int underlyingType: @type ref);
+
+@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type;
+@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type;
+type_literal_value(
+ unique int typ: @type_with_literal_value ref,
+ varchar(900) value: string ref);
+
+signature_types (
+ unique int id: @signature_type,
+ int kind: int ref,
+ varchar(900) tostring: string ref,
+ int type_parameters: int ref,
+ int required_params: int ref
+);
+
+is_abstract_signature(
+ unique int sig: @signature_type ref
+);
+
+signature_rest_parameter(
+ unique int sig: @signature_type ref,
+ int rest_param_arra_type: @type ref
+);
+
+case @signature_type.kind of
+ 0 = @function_signature_type
+| 1 = @constructor_signature_type
+;
+
+#keyset[typ, kind, index]
+type_contains_signature (
+ int typ: @type ref,
+ int kind: int ref, // constructor/call/index
+ int index: int ref, // ordering of overloaded signatures
+ int sig: @signature_type ref
+);
+
+#keyset[parent, index]
+signature_contains_type (
+ int child: @type ref,
+ int parent: @signature_type ref,
+ int index: int ref
+);
+
+#keyset[sig, index]
+signature_parameter_name (
+ int sig: @signature_type ref,
+ int index: int ref,
+ varchar(900) name: string ref
+);
+
+number_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+string_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+base_type_names(
+ int typeName: @symbol ref,
+ int baseTypeName: @symbol ref
+);
+
+self_types(
+ int typeName: @symbol ref,
+ int selfType: @type_reference ref
+);
+
+tuple_type_min_length(
+ unique int typ: @type ref,
+ int minLength: int ref
+);
+
+tuple_type_rest_index(
+ unique int typ: @type ref,
+ int index: int ref
+);
+
+// comments
+comments (unique int id: @comment,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(900) tostring: string ref);
+
+case @comment.kind of
+ 0 = @slashslash_comment
+| 1 = @slashstar_comment
+| 2 = @doc_comment
+| 3 = @html_comment_start
+| 4 = @htmlcommentend;
+
+@html_comment = @html_comment_start | @htmlcommentend;
+@line_comment = @slashslash_comment | @html_comment;
+@block_comment = @slashstar_comment | @doc_comment;
+
+// source lines
+lines (unique int id: @line,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(2) terminator: string ref);
+indentation (int file: @file ref,
+ int lineno: int ref,
+ varchar(1) indentChar: string ref,
+ int indentDepth: int ref);
+
+// JavaScript parse errors
+js_parse_errors (unique int id: @js_parse_error,
+ int toplevel: @toplevel ref,
+ varchar(900) message: string ref,
+ varchar(900) line: string ref);
+
+// regular expressions
+#keyset[parent, idx]
+regexpterm (unique int id: @regexpterm,
+ int kind: int ref,
+ int parent: @regexpparent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr;
+
+case @regexpterm.kind of
+ 0 = @regexp_alt
+| 1 = @regexp_seq
+| 2 = @regexp_caret
+| 3 = @regexp_dollar
+| 4 = @regexp_wordboundary
+| 5 = @regexp_nonwordboundary
+| 6 = @regexp_positive_lookahead
+| 7 = @regexp_negative_lookahead
+| 8 = @regexp_star
+| 9 = @regexp_plus
+| 10 = @regexp_opt
+| 11 = @regexp_range
+| 12 = @regexp_dot
+| 13 = @regexp_group
+| 14 = @regexp_normal_constant
+| 15 = @regexp_hex_escape
+| 16 = @regexp_unicode_escape
+| 17 = @regexp_dec_escape
+| 18 = @regexp_oct_escape
+| 19 = @regexp_ctrl_escape
+| 20 = @regexp_char_class_escape
+| 21 = @regexp_id_escape
+| 22 = @regexp_backref
+| 23 = @regexp_char_class
+| 24 = @regexp_char_range
+| 25 = @regexp_positive_lookbehind
+| 26 = @regexp_negative_lookbehind
+| 27 = @regexp_unicode_property_escape;
+
+regexp_parse_errors (unique int id: @regexp_parse_error,
+ int regexp: @regexpterm ref,
+ varchar(900) message: string ref);
+
+@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
+@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape;
+@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
+@regexp_constant = @regexp_normal_constant | @regexp_char_escape;
+@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead;
+@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind;
+@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind;
+@regexp_anchor = @regexp_dollar | @regexp_caret;
+
+is_greedy (int id: @regexp_quantifier ref);
+range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref);
+range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref);
+is_capture (unique int id: @regexp_group ref, int number: int ref);
+is_named_capture (unique int id: @regexp_group ref, string name: string ref);
+is_inverted (int id: @regexp_char_class ref);
+regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref);
+char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
+backref (unique int id: @regexp_backref ref, int value: int ref);
+named_backref (unique int id: @regexp_backref ref, string name: string ref);
+unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref);
+unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref);
+
+// tokens
+#keyset[toplevel, idx]
+tokeninfo (unique int id: @token,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ int idx: int ref,
+ varchar(900) value: string ref);
+
+case @token.kind of
+ 0 = @token_eof
+| 1 = @token_null_literal
+| 2 = @token_boolean_literal
+| 3 = @token_numeric_literal
+| 4 = @token_string_literal
+| 5 = @token_regular_expression
+| 6 = @token_identifier
+| 7 = @token_keyword
+| 8 = @token_punctuator;
+
+// associate comments with the token immediately following them (which may be EOF)
+next_token (int comment: @comment ref, int token: @token ref);
+
+// JSON
+#keyset[parent, idx]
+json (unique int id: @json_value,
+ int kind: int ref,
+ int parent: @json_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+json_literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @json_value ref);
+
+json_properties (int obj: @json_object ref,
+ varchar(900) property: string ref,
+ int value: @json_value ref);
+
+json_errors (unique int id: @json_parse_error,
+ varchar(900) message: string ref);
+
+json_locations(unique int locatable: @json_locatable ref,
+ int location: @location_default ref);
+
+case @json_value.kind of
+ 0 = @json_null
+| 1 = @json_boolean
+| 2 = @json_number
+| 3 = @json_string
+| 4 = @json_array
+| 5 = @json_object;
+
+@json_parent = @json_object | @json_array | @file;
+
+@json_locatable = @json_value | @json_parse_error;
+
+// locations
+@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr;
+
+@locatable = @file
+ | @ast_node
+ | @comment
+ | @line
+ | @js_parse_error | @regexp_parse_error
+ | @regexpterm
+ | @json_locatable
+ | @token
+ | @cfg_node
+ | @jsdoc | @jsdoc_type_expr | @jsdoc_tag
+ | @yaml_locatable
+ | @xmllocatable
+ | @configLocatable
+ | @template_placeholder_tag;
+
+hasLocation (unique int locatable: @locatable ref,
+ int location: @location ref);
+
+// CFG
+entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref);
+exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref);
+guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref);
+case @guard_node.kind of
+ 0 = @falsy_guard
+| 1 = @truthy_guard;
+@condition_guard = @falsy_guard | @truthy_guard;
+
+@synthetic_cfg_node = @entry_node | @exit_node | @guard_node;
+@cfg_node = @synthetic_cfg_node | @expr_parent;
+
+successor (int pred: @cfg_node ref, int succ: @cfg_node ref);
+
+// JSDoc comments
+jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref);
+#keyset[parent, idx]
+jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref,
+ int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref);
+jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+
+#keyset[parent, idx]
+jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
+ int kind: int ref,
+ int parent: @jsdoc_type_expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+case @jsdoc_type_expr.kind of
+ 0 = @jsdoc_any_type_expr
+| 1 = @jsdoc_null_type_expr
+| 2 = @jsdoc_undefined_type_expr
+| 3 = @jsdoc_unknown_type_expr
+| 4 = @jsdoc_void_type_expr
+| 5 = @jsdoc_named_type_expr
+| 6 = @jsdoc_applied_type_expr
+| 7 = @jsdoc_nullable_type_expr
+| 8 = @jsdoc_non_nullable_type_expr
+| 9 = @jsdoc_record_type_expr
+| 10 = @jsdoc_array_type_expr
+| 11 = @jsdoc_union_type_expr
+| 12 = @jsdoc_function_type_expr
+| 13 = @jsdoc_optional_type_expr
+| 14 = @jsdoc_rest_type_expr
+;
+
+#keyset[id, idx]
+jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref);
+jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref);
+jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref);
+
+@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag;
+
+jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref);
+
+@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property;
+
+@optionalchainable = @call_expr | @propaccess;
+
+isOptionalChaining(int id: @optionalchainable ref);
+
+/**
+ * The time taken for the extraction of a file.
+ * This table contains non-deterministic content.
+ *
+ * The sum of the `time` column for each (`file`, `timerKind`) pair
+ * is the total time taken for extraction of `file`. The `extractionPhase`
+ * column provides a granular view of the extraction time of the file.
+ */
+extraction_time(
+ int file : @file ref,
+ // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`.
+ int extractionPhase: int ref,
+ // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds
+ int timerKind: int ref,
+ float time: float ref
+)
+
+/**
+* Non-timing related data for the extraction of a single file.
+* This table contains non-deterministic content.
+*/
+extraction_data(
+ int file : @file ref,
+ // the absolute path to the cache file
+ varchar(900) cacheFile: string ref,
+ boolean fromCache: boolean ref,
+ int length: int ref
+)
+
+/*- YAML -*/
+
+#keyset[parent, idx]
+yaml (unique int id: @yaml_node,
+ int kind: int ref,
+ int parent: @yaml_node_parent ref,
+ int idx: int ref,
+ string tag: string ref,
+ string tostring: string ref);
+
+case @yaml_node.kind of
+ 0 = @yaml_scalar_node
+| 1 = @yaml_mapping_node
+| 2 = @yaml_sequence_node
+| 3 = @yaml_alias_node
+;
+
+@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node;
+
+@yaml_node_parent = @yaml_collection_node | @file;
+
+yaml_anchors (unique int node: @yaml_node ref,
+ string anchor: string ref);
+
+yaml_aliases (unique int alias: @yaml_alias_node ref,
+ string target: string ref);
+
+yaml_scalars (unique int scalar: @yaml_scalar_node ref,
+ int style: int ref,
+ string value: string ref);
+
+yaml_errors (unique int id: @yaml_error,
+ string message: string ref);
+
+yaml_locations(unique int locatable: @yaml_locatable ref,
+ int location: @location_default ref);
+
+@yaml_locatable = @yaml_node | @yaml_error;
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*- Configuration files with key value pairs -*/
+
+configs(
+ unique int id: @config
+);
+
+configNames(
+ unique int id: @configName,
+ int config: @config ref,
+ string name: string ref
+);
+
+configValues(
+ unique int id: @configValue,
+ int config: @config ref,
+ string value: string ref
+);
+
+configLocations(
+ int locatable: @configLocatable ref,
+ int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme
new file mode 100644
index 00000000000..c88c69174bd
--- /dev/null
+++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme
@@ -0,0 +1,1190 @@
+/*** Standard fragments ***/
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- JavaScript-specific part -*/
+
+@location = @location_default
+
+@sourceline = @locatable;
+
+filetype(
+ int file: @file ref,
+ string filetype: string ref
+)
+
+// top-level code fragments
+toplevels (unique int id: @toplevel,
+ int kind: int ref);
+
+is_externs (int toplevel: @toplevel ref);
+
+case @toplevel.kind of
+ 0 = @script
+| 1 = @inline_script
+| 2 = @event_handler
+| 3 = @javascript_url
+| 4 = @template_toplevel;
+
+is_module (int tl: @toplevel ref);
+is_nodejs (int tl: @toplevel ref);
+is_es2015_module (int tl: @toplevel ref);
+is_closure_module (int tl: @toplevel ref);
+
+@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag;
+toplevel_parent_xml_node(
+ unique int toplevel: @toplevel ref,
+ int xmlnode: @xml_node_with_code ref);
+
+xml_element_parent_expression(
+ unique int xmlnode: @xmlelement ref,
+ int expression: @expr ref,
+ int index: int ref);
+
+// statements
+#keyset[parent, idx]
+stmts (unique int id: @stmt,
+ int kind: int ref,
+ int parent: @stmt_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+stmt_containers (unique int stmt: @stmt ref,
+ int container: @stmt_container ref);
+
+jump_targets (unique int jump: @stmt ref,
+ int target: @stmt ref);
+
+@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer;
+@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration;
+
+case @stmt.kind of
+ 0 = @empty_stmt
+| 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @labeled_stmt
+| 5 = @break_stmt
+| 6 = @continue_stmt
+| 7 = @with_stmt
+| 8 = @switch_stmt
+| 9 = @return_stmt
+| 10 = @throw_stmt
+| 11 = @try_stmt
+| 12 = @while_stmt
+| 13 = @do_while_stmt
+| 14 = @for_stmt
+| 15 = @for_in_stmt
+| 16 = @debugger_stmt
+| 17 = @function_decl_stmt
+| 18 = @var_decl_stmt
+| 19 = @case
+| 20 = @catch_clause
+| 21 = @for_of_stmt
+| 22 = @const_decl_stmt
+| 23 = @let_stmt
+| 24 = @legacy_let_stmt
+| 25 = @for_each_stmt
+| 26 = @class_decl_stmt
+| 27 = @import_declaration
+| 28 = @export_all_declaration
+| 29 = @export_default_declaration
+| 30 = @export_named_declaration
+| 31 = @namespace_declaration
+| 32 = @import_equals_declaration
+| 33 = @export_assign_declaration
+| 34 = @interface_declaration
+| 35 = @type_alias_declaration
+| 36 = @enum_declaration
+| 37 = @external_module_declaration
+| 38 = @export_as_namespace_declaration
+| 39 = @global_augmentation_declaration
+| 40 = @using_decl_stmt
+;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt;
+
+@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration;
+
+@namespace_definition = @namespace_declaration | @enum_declaration;
+@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member;
+
+is_instantiated(unique int decl: @namespace_declaration ref);
+
+@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field;
+has_declare_keyword(unique int stmt: @declarable_node ref);
+
+is_for_await_of(unique int forof: @for_of_stmt ref);
+
+// expressions
+#keyset[parent, idx]
+exprs (unique int id: @expr,
+ int kind: int ref,
+ int parent: @expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @expr_or_type ref);
+
+enclosing_stmt (unique int expr: @expr_or_type ref,
+ int stmt: @stmt ref);
+
+expr_containers (unique int expr: @expr_or_type ref,
+ int container: @stmt_container ref);
+
+array_size (unique int ae: @arraylike ref,
+ int sz: int ref);
+
+is_delegating (int yield: @yield_expr ref);
+
+@expr_or_stmt = @expr | @stmt;
+@expr_or_type = @expr | @typeexpr;
+@expr_parent = @expr_or_stmt | @property | @function_typeexpr;
+@arraylike = @array_expr | @array_pattern;
+@type_annotation = @typeexpr | @jsdoc_type_expr;
+@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel;
+
+case @expr.kind of
+ 0 = @label
+| 1 = @null_literal
+| 2 = @boolean_literal
+| 3 = @number_literal
+| 4 = @string_literal
+| 5 = @regexp_literal
+| 6 = @this_expr
+| 7 = @array_expr
+| 8 = @obj_expr
+| 9 = @function_expr
+| 10 = @seq_expr
+| 11 = @conditional_expr
+| 12 = @new_expr
+| 13 = @call_expr
+| 14 = @dot_expr
+| 15 = @index_expr
+| 16 = @neg_expr
+| 17 = @plus_expr
+| 18 = @log_not_expr
+| 19 = @bit_not_expr
+| 20 = @typeof_expr
+| 21 = @void_expr
+| 22 = @delete_expr
+| 23 = @eq_expr
+| 24 = @neq_expr
+| 25 = @eqq_expr
+| 26 = @neqq_expr
+| 27 = @lt_expr
+| 28 = @le_expr
+| 29 = @gt_expr
+| 30 = @ge_expr
+| 31 = @lshift_expr
+| 32 = @rshift_expr
+| 33 = @urshift_expr
+| 34 = @add_expr
+| 35 = @sub_expr
+| 36 = @mul_expr
+| 37 = @div_expr
+| 38 = @mod_expr
+| 39 = @bitor_expr
+| 40 = @xor_expr
+| 41 = @bitand_expr
+| 42 = @in_expr
+| 43 = @instanceof_expr
+| 44 = @logand_expr
+| 45 = @logor_expr
+| 47 = @assign_expr
+| 48 = @assign_add_expr
+| 49 = @assign_sub_expr
+| 50 = @assign_mul_expr
+| 51 = @assign_div_expr
+| 52 = @assign_mod_expr
+| 53 = @assign_lshift_expr
+| 54 = @assign_rshift_expr
+| 55 = @assign_urshift_expr
+| 56 = @assign_or_expr
+| 57 = @assign_xor_expr
+| 58 = @assign_and_expr
+| 59 = @preinc_expr
+| 60 = @postinc_expr
+| 61 = @predec_expr
+| 62 = @postdec_expr
+| 63 = @par_expr
+| 64 = @var_declarator
+| 65 = @arrow_function_expr
+| 66 = @spread_element
+| 67 = @array_pattern
+| 68 = @object_pattern
+| 69 = @yield_expr
+| 70 = @tagged_template_expr
+| 71 = @template_literal
+| 72 = @template_element
+| 73 = @array_comprehension_expr
+| 74 = @generator_expr
+| 75 = @for_in_comprehension_block
+| 76 = @for_of_comprehension_block
+| 77 = @legacy_letexpr
+| 78 = @var_decl
+| 79 = @proper_varaccess
+| 80 = @class_expr
+| 81 = @super_expr
+| 82 = @newtarget_expr
+| 83 = @named_import_specifier
+| 84 = @import_default_specifier
+| 85 = @import_namespace_specifier
+| 86 = @named_export_specifier
+| 87 = @exp_expr
+| 88 = @assign_exp_expr
+| 89 = @jsx_element
+| 90 = @jsx_qualified_name
+| 91 = @jsx_empty_expr
+| 92 = @await_expr
+| 93 = @function_sent_expr
+| 94 = @decorator
+| 95 = @export_default_specifier
+| 96 = @export_namespace_specifier
+| 97 = @bind_expr
+| 98 = @external_module_reference
+| 99 = @dynamic_import
+| 100 = @expression_with_type_arguments
+| 101 = @prefix_type_assertion
+| 102 = @as_type_assertion
+| 103 = @export_varaccess
+| 104 = @decorator_list
+| 105 = @non_null_assertion
+| 106 = @bigint_literal
+| 107 = @nullishcoalescing_expr
+| 108 = @e4x_xml_anyname
+| 109 = @e4x_xml_static_attribute_selector
+| 110 = @e4x_xml_dynamic_attribute_selector
+| 111 = @e4x_xml_filter_expression
+| 112 = @e4x_xml_static_qualident
+| 113 = @e4x_xml_dynamic_qualident
+| 114 = @e4x_xml_dotdotexpr
+| 115 = @import_meta_expr
+| 116 = @assignlogandexpr
+| 117 = @assignlogorexpr
+| 118 = @assignnullishcoalescingexpr
+| 119 = @template_pipe_ref
+| 120 = @generated_code_expr
+| 121 = @satisfies_expr
+;
+
+@varaccess = @proper_varaccess | @export_varaccess;
+@varref = @var_decl | @varaccess;
+
+@identifier = @label | @varref | @type_identifier;
+
+@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal;
+
+@propaccess = @dot_expr | @index_expr;
+
+@invokeexpr = @new_expr | @call_expr;
+
+@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element;
+
+@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr;
+
+@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr;
+
+@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr;
+
+@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr;
+
+@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr;
+
+@pattern = @varref | @array_pattern | @object_pattern;
+
+@comprehension_expr = @array_comprehension_expr | @generator_expr;
+
+@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block;
+
+@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier;
+
+@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier;
+
+@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier;
+
+@type_assertion = @as_type_assertion | @prefix_type_assertion;
+
+@class_definition = @class_decl_stmt | @class_expr;
+@interface_definition = @interface_declaration | @interface_typeexpr;
+@class_or_interface = @class_definition | @interface_definition;
+
+@lexical_decl = @var_decl | @type_decl;
+@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access;
+@lexical_ref = @lexical_decl | @lexical_access;
+
+@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector;
+@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident;
+
+expr_contains_template_tag_location(
+ int expr: @expr ref,
+ int location: @location ref
+);
+
+@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file;
+
+template_placeholder_tag_info(
+ unique int node: @template_placeholder_tag,
+ int parentNode: @template_placeholder_tag_parent ref,
+ varchar(900) raw: string ref
+);
+
+// scopes
+scopes (unique int id: @scope,
+ int kind: int ref);
+
+case @scope.kind of
+ 0 = @global_scope
+| 1 = @function_scope
+| 2 = @catch_scope
+| 3 = @module_scope
+| 4 = @block_scope
+| 5 = @for_scope
+| 6 = @for_in_scope // for-of scopes work the same as for-in scopes
+| 7 = @comprehension_block_scope
+| 8 = @class_expr_scope
+| 9 = @namespace_scope
+| 10 = @class_decl_scope
+| 11 = @interface_scope
+| 12 = @type_alias_scope
+| 13 = @mapped_type_scope
+| 14 = @enum_scope
+| 15 = @external_module_scope
+| 16 = @conditional_type_scope;
+
+scopenodes (unique int node: @ast_node ref,
+ int scope: @scope ref);
+
+scopenesting (unique int inner: @scope ref,
+ int outer: @scope ref);
+
+// functions
+@function = @function_decl_stmt | @function_expr | @arrow_function_expr;
+
+@parameterized = @function | @catch_clause;
+@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr;
+
+is_generator (int fun: @function ref);
+has_rest_parameter (int fun: @function ref);
+is_async (int fun: @function ref);
+
+// variables and lexically scoped type names
+#keyset[scope, name]
+variables (unique int id: @variable,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_type_names (unique int id: @local_type_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+#keyset[scope, name]
+local_namespace_names (unique int id: @local_namespace_name,
+ varchar(900) name: string ref,
+ int scope: @scope ref);
+
+is_arguments_object (int id: @variable ref);
+
+@lexical_name = @variable | @local_type_name | @local_namespace_name;
+
+@bind_id = @varaccess | @local_var_type_access;
+bind (unique int id: @bind_id ref,
+ int decl: @variable ref);
+
+decl (unique int id: @var_decl ref,
+ int decl: @variable ref);
+
+@typebind_id = @local_type_access | @export_varaccess;
+typebind (unique int id: @typebind_id ref,
+ int decl: @local_type_name ref);
+
+@typedecl_id = @type_decl | @var_decl;
+typedecl (unique int id: @typedecl_id ref,
+ int decl: @local_type_name ref);
+
+namespacedecl (unique int id: @var_decl ref,
+ int decl: @local_namespace_name ref);
+
+@namespacebind_id = @local_namespace_access | @export_varaccess;
+namespacebind (unique int id: @namespacebind_id ref,
+ int decl: @local_namespace_name ref);
+
+
+// properties in object literals, property patterns in object patterns, and method declarations in classes
+#keyset[parent, index]
+properties (unique int id: @property,
+ int parent: @property_parent ref,
+ int index: int ref,
+ int kind: int ref,
+ varchar(900) tostring: string ref);
+
+case @property.kind of
+ 0 = @value_property
+| 1 = @property_getter
+| 2 = @property_setter
+| 3 = @jsx_attribute
+| 4 = @function_call_signature
+| 5 = @constructor_call_signature
+| 6 = @index_signature
+| 7 = @enum_member
+| 8 = @proper_field
+| 9 = @parameter_field
+| 10 = @static_initializer
+;
+
+@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration;
+@property_accessor = @property_getter | @property_setter;
+@call_signature = @function_call_signature | @constructor_call_signature;
+@field = @proper_field | @parameter_field;
+@field_or_vardeclarator = @field | @var_declarator;
+
+is_computed (int id: @property ref);
+is_method (int id: @property ref);
+is_static (int id: @property ref);
+is_abstract_member (int id: @property ref);
+is_const_enum (int id: @enum_declaration ref);
+is_abstract_class (int id: @class_decl_stmt ref);
+
+has_public_keyword (int id: @property ref);
+has_private_keyword (int id: @property ref);
+has_protected_keyword (int id: @property ref);
+has_readonly_keyword (int id: @property ref);
+has_type_keyword (int id: @type_keyword_operand ref);
+is_optional_member (int id: @property ref);
+has_definite_assignment_assertion (int id: @field_or_vardeclarator ref);
+is_optional_parameter_declaration (unique int parameter: @pattern ref);
+
+#keyset[constructor, param_index]
+parameter_fields(
+ unique int field: @parameter_field ref,
+ int constructor: @function_expr ref,
+ int param_index: int ref
+);
+
+// types
+#keyset[parent, idx]
+typeexprs (
+ unique int id: @typeexpr,
+ int kind: int ref,
+ int parent: @typeexpr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref
+);
+
+case @typeexpr.kind of
+ 0 = @local_type_access
+| 1 = @type_decl
+| 2 = @keyword_typeexpr
+| 3 = @string_literal_typeexpr
+| 4 = @number_literal_typeexpr
+| 5 = @boolean_literal_typeexpr
+| 6 = @array_typeexpr
+| 7 = @union_typeexpr
+| 8 = @indexed_access_typeexpr
+| 9 = @intersection_typeexpr
+| 10 = @parenthesized_typeexpr
+| 11 = @tuple_typeexpr
+| 12 = @keyof_typeexpr
+| 13 = @qualified_type_access
+| 14 = @generic_typeexpr
+| 15 = @type_label
+| 16 = @typeof_typeexpr
+| 17 = @local_var_type_access
+| 18 = @qualified_var_type_access
+| 19 = @this_var_type_access
+| 20 = @predicate_typeexpr
+| 21 = @interface_typeexpr
+| 22 = @type_parameter
+| 23 = @plain_function_typeexpr
+| 24 = @constructor_typeexpr
+| 25 = @local_namespace_access
+| 26 = @qualified_namespace_access
+| 27 = @mapped_typeexpr
+| 28 = @conditional_typeexpr
+| 29 = @infer_typeexpr
+| 30 = @import_type_access
+| 31 = @import_namespace_access
+| 32 = @import_var_type_access
+| 33 = @optional_typeexpr
+| 34 = @rest_typeexpr
+| 35 = @bigint_literal_typeexpr
+| 36 = @readonly_typeexpr
+| 37 = @template_literal_typeexpr
+;
+
+@typeref = @typeaccess | @type_decl;
+@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access;
+@typeexpr_parent = @expr | @stmt | @property | @typeexpr;
+@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr;
+@typeaccess = @local_type_access | @qualified_type_access | @import_type_access;
+@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access;
+@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access;
+@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access;
+
+@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr;
+
+// types
+types (
+ unique int id: @type,
+ int kind: int ref,
+ varchar(900) tostring: string ref
+);
+
+#keyset[parent, idx]
+type_child (
+ int child: @type ref,
+ int parent: @type ref,
+ int idx: int ref
+);
+
+case @type.kind of
+ 0 = @any_type
+| 1 = @string_type
+| 2 = @number_type
+| 3 = @union_type
+| 4 = @true_type
+| 5 = @false_type
+| 6 = @type_reference
+| 7 = @object_type
+| 8 = @canonical_type_variable_type
+| 9 = @typeof_type
+| 10 = @void_type
+| 11 = @undefined_type
+| 12 = @null_type
+| 13 = @never_type
+| 14 = @plain_symbol_type
+| 15 = @unique_symbol_type
+| 16 = @objectkeyword_type
+| 17 = @intersection_type
+| 18 = @tuple_type
+| 19 = @lexical_type_variable_type
+| 20 = @this_type
+| 21 = @number_literal_type
+| 22 = @string_literal_type
+| 23 = @unknown_type
+| 24 = @bigint_type
+| 25 = @bigint_literal_type
+;
+
+@boolean_literal_type = @true_type | @false_type;
+@symbol_type = @plain_symbol_type | @unique_symbol_type;
+@union_or_intersection_type = @union_type | @intersection_type;
+@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type;
+
+has_asserts_keyword(int node: @predicate_typeexpr ref);
+
+@typed_ast_node = @expr | @typeexpr | @function;
+ast_node_type(
+ unique int node: @typed_ast_node ref,
+ int typ: @type ref);
+
+declared_function_signature(
+ unique int node: @function ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_signature(
+ unique int node: @invokeexpr ref,
+ int sig: @signature_type ref
+);
+
+invoke_expr_overload_index(
+ unique int node: @invokeexpr ref,
+ int index: int ref
+);
+
+symbols (
+ unique int id: @symbol,
+ int kind: int ref,
+ varchar(900) name: string ref
+);
+
+symbol_parent (
+ unique int symbol: @symbol ref,
+ int parent: @symbol ref
+);
+
+symbol_module (
+ int symbol: @symbol ref,
+ varchar(900) moduleName: string ref
+);
+
+symbol_global (
+ int symbol: @symbol ref,
+ varchar(900) globalName: string ref
+);
+
+case @symbol.kind of
+ 0 = @root_symbol
+| 1 = @member_symbol
+| 2 = @other_symbol
+;
+
+@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type;
+@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration;
+
+ast_node_symbol(
+ unique int node: @ast_node_with_symbol ref,
+ int symbol: @symbol ref);
+
+type_symbol(
+ unique int typ: @type_with_symbol ref,
+ int symbol: @symbol ref);
+
+#keyset[typ, name]
+type_property(
+ int typ: @type ref,
+ varchar(900) name: string ref,
+ int propertyType: @type ref);
+
+type_alias(
+ unique int aliasType: @type ref,
+ int underlyingType: @type ref);
+
+@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type;
+@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type;
+type_literal_value(
+ unique int typ: @type_with_literal_value ref,
+ varchar(900) value: string ref);
+
+signature_types (
+ unique int id: @signature_type,
+ int kind: int ref,
+ varchar(900) tostring: string ref,
+ int type_parameters: int ref,
+ int required_params: int ref
+);
+
+is_abstract_signature(
+ unique int sig: @signature_type ref
+);
+
+signature_rest_parameter(
+ unique int sig: @signature_type ref,
+ int rest_param_arra_type: @type ref
+);
+
+case @signature_type.kind of
+ 0 = @function_signature_type
+| 1 = @constructor_signature_type
+;
+
+#keyset[typ, kind, index]
+type_contains_signature (
+ int typ: @type ref,
+ int kind: int ref, // constructor/call/index
+ int index: int ref, // ordering of overloaded signatures
+ int sig: @signature_type ref
+);
+
+#keyset[parent, index]
+signature_contains_type (
+ int child: @type ref,
+ int parent: @signature_type ref,
+ int index: int ref
+);
+
+#keyset[sig, index]
+signature_parameter_name (
+ int sig: @signature_type ref,
+ int index: int ref,
+ varchar(900) name: string ref
+);
+
+number_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+string_index_type (
+ unique int baseType: @type ref,
+ int propertyType: @type ref
+);
+
+base_type_names(
+ int typeName: @symbol ref,
+ int baseTypeName: @symbol ref
+);
+
+self_types(
+ int typeName: @symbol ref,
+ int selfType: @type_reference ref
+);
+
+tuple_type_min_length(
+ unique int typ: @type ref,
+ int minLength: int ref
+);
+
+tuple_type_rest_index(
+ unique int typ: @type ref,
+ int index: int ref
+);
+
+// comments
+comments (unique int id: @comment,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(900) tostring: string ref);
+
+case @comment.kind of
+ 0 = @slashslash_comment
+| 1 = @slashstar_comment
+| 2 = @doc_comment
+| 3 = @html_comment_start
+| 4 = @htmlcommentend;
+
+@html_comment = @html_comment_start | @htmlcommentend;
+@line_comment = @slashslash_comment | @html_comment;
+@block_comment = @slashstar_comment | @doc_comment;
+
+// source lines
+lines (unique int id: @line,
+ int toplevel: @toplevel ref,
+ varchar(900) text: string ref,
+ varchar(2) terminator: string ref);
+indentation (int file: @file ref,
+ int lineno: int ref,
+ varchar(1) indentChar: string ref,
+ int indentDepth: int ref);
+
+// JavaScript parse errors
+js_parse_errors (unique int id: @js_parse_error,
+ int toplevel: @toplevel ref,
+ varchar(900) message: string ref,
+ varchar(900) line: string ref);
+
+// regular expressions
+#keyset[parent, idx]
+regexpterm (unique int id: @regexpterm,
+ int kind: int ref,
+ int parent: @regexpparent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr;
+
+case @regexpterm.kind of
+ 0 = @regexp_alt
+| 1 = @regexp_seq
+| 2 = @regexp_caret
+| 3 = @regexp_dollar
+| 4 = @regexp_wordboundary
+| 5 = @regexp_nonwordboundary
+| 6 = @regexp_positive_lookahead
+| 7 = @regexp_negative_lookahead
+| 8 = @regexp_star
+| 9 = @regexp_plus
+| 10 = @regexp_opt
+| 11 = @regexp_range
+| 12 = @regexp_dot
+| 13 = @regexp_group
+| 14 = @regexp_normal_constant
+| 15 = @regexp_hex_escape
+| 16 = @regexp_unicode_escape
+| 17 = @regexp_dec_escape
+| 18 = @regexp_oct_escape
+| 19 = @regexp_ctrl_escape
+| 20 = @regexp_char_class_escape
+| 21 = @regexp_id_escape
+| 22 = @regexp_backref
+| 23 = @regexp_char_class
+| 24 = @regexp_char_range
+| 25 = @regexp_positive_lookbehind
+| 26 = @regexp_negative_lookbehind
+| 27 = @regexp_unicode_property_escape;
+
+regexp_parse_errors (unique int id: @regexp_parse_error,
+ int regexp: @regexpterm ref,
+ varchar(900) message: string ref);
+
+@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
+@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape;
+@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
+@regexp_constant = @regexp_normal_constant | @regexp_char_escape;
+@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead;
+@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind;
+@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind;
+@regexp_anchor = @regexp_dollar | @regexp_caret;
+
+is_greedy (int id: @regexp_quantifier ref);
+range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref);
+range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref);
+is_capture (unique int id: @regexp_group ref, int number: int ref);
+is_named_capture (unique int id: @regexp_group ref, string name: string ref);
+is_inverted (int id: @regexp_char_class ref);
+regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref);
+char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
+backref (unique int id: @regexp_backref ref, int value: int ref);
+named_backref (unique int id: @regexp_backref ref, string name: string ref);
+unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref);
+unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref);
+
+// tokens
+#keyset[toplevel, idx]
+tokeninfo (unique int id: @token,
+ int kind: int ref,
+ int toplevel: @toplevel ref,
+ int idx: int ref,
+ varchar(900) value: string ref);
+
+case @token.kind of
+ 0 = @token_eof
+| 1 = @token_null_literal
+| 2 = @token_boolean_literal
+| 3 = @token_numeric_literal
+| 4 = @token_string_literal
+| 5 = @token_regular_expression
+| 6 = @token_identifier
+| 7 = @token_keyword
+| 8 = @token_punctuator;
+
+// associate comments with the token immediately following them (which may be EOF)
+next_token (int comment: @comment ref, int token: @token ref);
+
+// JSON
+#keyset[parent, idx]
+json (unique int id: @json_value,
+ int kind: int ref,
+ int parent: @json_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+
+json_literals (varchar(900) value: string ref,
+ varchar(900) raw: string ref,
+ unique int expr: @json_value ref);
+
+json_properties (int obj: @json_object ref,
+ varchar(900) property: string ref,
+ int value: @json_value ref);
+
+json_errors (unique int id: @json_parse_error,
+ varchar(900) message: string ref);
+
+json_locations(unique int locatable: @json_locatable ref,
+ int location: @location_default ref);
+
+case @json_value.kind of
+ 0 = @json_null
+| 1 = @json_boolean
+| 2 = @json_number
+| 3 = @json_string
+| 4 = @json_array
+| 5 = @json_object;
+
+@json_parent = @json_object | @json_array | @file;
+
+@json_locatable = @json_value | @json_parse_error;
+
+// locations
+@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr;
+
+@locatable = @file
+ | @ast_node
+ | @comment
+ | @line
+ | @js_parse_error | @regexp_parse_error
+ | @regexpterm
+ | @json_locatable
+ | @token
+ | @cfg_node
+ | @jsdoc | @jsdoc_type_expr | @jsdoc_tag
+ | @yaml_locatable
+ | @xmllocatable
+ | @configLocatable
+ | @template_placeholder_tag;
+
+hasLocation (unique int locatable: @locatable ref,
+ int location: @location ref);
+
+// CFG
+entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref);
+exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref);
+guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref);
+case @guard_node.kind of
+ 0 = @falsy_guard
+| 1 = @truthy_guard;
+@condition_guard = @falsy_guard | @truthy_guard;
+
+@synthetic_cfg_node = @entry_node | @exit_node | @guard_node;
+@cfg_node = @synthetic_cfg_node | @expr_parent;
+
+successor (int pred: @cfg_node ref, int succ: @cfg_node ref);
+
+// JSDoc comments
+jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref);
+#keyset[parent, idx]
+jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref,
+ int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref);
+jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
+
+#keyset[parent, idx]
+jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
+ int kind: int ref,
+ int parent: @jsdoc_type_expr_parent ref,
+ int idx: int ref,
+ varchar(900) tostring: string ref);
+case @jsdoc_type_expr.kind of
+ 0 = @jsdoc_any_type_expr
+| 1 = @jsdoc_null_type_expr
+| 2 = @jsdoc_undefined_type_expr
+| 3 = @jsdoc_unknown_type_expr
+| 4 = @jsdoc_void_type_expr
+| 5 = @jsdoc_named_type_expr
+| 6 = @jsdoc_applied_type_expr
+| 7 = @jsdoc_nullable_type_expr
+| 8 = @jsdoc_non_nullable_type_expr
+| 9 = @jsdoc_record_type_expr
+| 10 = @jsdoc_array_type_expr
+| 11 = @jsdoc_union_type_expr
+| 12 = @jsdoc_function_type_expr
+| 13 = @jsdoc_optional_type_expr
+| 14 = @jsdoc_rest_type_expr
+;
+
+#keyset[id, idx]
+jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref);
+jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref);
+jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref);
+
+@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag;
+
+jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref);
+
+@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property;
+
+@optionalchainable = @call_expr | @propaccess;
+
+isOptionalChaining(int id: @optionalchainable ref);
+
+/**
+ * The time taken for the extraction of a file.
+ * This table contains non-deterministic content.
+ *
+ * The sum of the `time` column for each (`file`, `timerKind`) pair
+ * is the total time taken for extraction of `file`. The `extractionPhase`
+ * column provides a granular view of the extraction time of the file.
+ */
+extraction_time(
+ int file : @file ref,
+ // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`.
+ int extractionPhase: int ref,
+ // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds
+ int timerKind: int ref,
+ float time: float ref
+)
+
+/**
+* Non-timing related data for the extraction of a single file.
+* This table contains non-deterministic content.
+*/
+extraction_data(
+ int file : @file ref,
+ // the absolute path to the cache file
+ varchar(900) cacheFile: string ref,
+ boolean fromCache: boolean ref,
+ int length: int ref
+)
+
+/*- YAML -*/
+
+#keyset[parent, idx]
+yaml (unique int id: @yaml_node,
+ int kind: int ref,
+ int parent: @yaml_node_parent ref,
+ int idx: int ref,
+ string tag: string ref,
+ string tostring: string ref);
+
+case @yaml_node.kind of
+ 0 = @yaml_scalar_node
+| 1 = @yaml_mapping_node
+| 2 = @yaml_sequence_node
+| 3 = @yaml_alias_node
+;
+
+@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node;
+
+@yaml_node_parent = @yaml_collection_node | @file;
+
+yaml_anchors (unique int node: @yaml_node ref,
+ string anchor: string ref);
+
+yaml_aliases (unique int alias: @yaml_alias_node ref,
+ string target: string ref);
+
+yaml_scalars (unique int scalar: @yaml_scalar_node ref,
+ int style: int ref,
+ string value: string ref);
+
+yaml_errors (unique int id: @yaml_error,
+ string message: string ref);
+
+yaml_locations(unique int locatable: @yaml_locatable ref,
+ int location: @location_default ref);
+
+@yaml_locatable = @yaml_node | @yaml_error;
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*- Configuration files with key value pairs -*/
+
+configs(
+ unique int id: @config
+);
+
+configNames(
+ unique int id: @configName,
+ int config: @config ref,
+ string name: string ref
+);
+
+configValues(
+ unique int id: @configValue,
+ int config: @config ref,
+ string value: string ref
+);
+
+configLocations(
+ int locatable: @configLocatable ref,
+ int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties
new file mode 100644
index 00000000000..2937b1f0cc2
--- /dev/null
+++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties
@@ -0,0 +1,2 @@
+description: add support for TypeScript 5.2
+compatibility: backwards
diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md
index d77e565ad90..3cf78549f64 100644
--- a/javascript/ql/src/CHANGELOG.md
+++ b/javascript/ql/src/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.7.4
+
+### Minor Analysis Improvements
+
+* Files larger than 10 MB are no longer be extracted or analyzed.
+* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call.
+
+### Bug Fixes
+
+* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias.
+
## 0.7.3
No user-facing changes.
diff --git a/javascript/ql/src/Declarations/AssignmentToConst.ql b/javascript/ql/src/Declarations/AssignmentToConst.ql
index e9efb03fd83..f2a24832c6a 100644
--- a/javascript/ql/src/Declarations/AssignmentToConst.ql
+++ b/javascript/ql/src/Declarations/AssignmentToConst.ql
@@ -13,8 +13,9 @@
import javascript
import semmle.javascript.RestrictedLocations
-from ConstDeclStmt cds, VariableDeclarator decl, VarDef def, Variable v
+from DeclStmt cds, VariableDeclarator decl, VarDef def, Variable v
where
+ (cds instanceof ConstDeclStmt or cds instanceof UsingDeclStmt) and
decl = cds.getADecl() and
def.getAVariable() = v and
decl.getBindingPattern().getAVariable() = v and
diff --git a/javascript/ql/src/Statements/UselessConditional.ql b/javascript/ql/src/Statements/UselessConditional.ql
index 600fff5fb1c..cc70defa7b2 100644
--- a/javascript/ql/src/Statements/UselessConditional.ql
+++ b/javascript/ql/src/Statements/UselessConditional.ql
@@ -39,6 +39,8 @@ predicate isSymbolicConstant(Variable v) {
exists(VarDef vd | vd = getSingleDef(v) |
vd.(VariableDeclarator).getDeclStmt() instanceof ConstDeclStmt
or
+ vd.(VariableDeclarator).getDeclStmt() instanceof UsingDeclStmt
+ or
isConstant(vd.getSource())
)
}
diff --git a/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md b/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md
deleted file mode 100644
index 66769f2b8fa..00000000000
--- a/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: fix
----
-* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias.
diff --git a/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md b/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md
deleted file mode 100644
index fc82b3b5a3f..00000000000
--- a/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Files larger than 10 MB are no longer be extracted or analyzed.
diff --git a/javascript/ql/src/change-notes/2023-08-23-import-path-string.md b/javascript/ql/src/change-notes/2023-08-23-import-path-string.md
deleted file mode 100644
index 64a70c1fe10..00000000000
--- a/javascript/ql/src/change-notes/2023-08-23-import-path-string.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call.
diff --git a/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md b/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md
new file mode 100644
index 00000000000..e6104889ba6
--- /dev/null
+++ b/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md
@@ -0,0 +1,4 @@
+---
+category: fix
+---
+* Fixed an extractor crash that could occur in projects containing TypeScript files larger than 10 MB.
diff --git a/javascript/ql/src/change-notes/released/0.7.4.md b/javascript/ql/src/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..55118b12535
--- /dev/null
+++ b/javascript/ql/src/change-notes/released/0.7.4.md
@@ -0,0 +1,10 @@
+## 0.7.4
+
+### Minor Analysis Improvements
+
+* Files larger than 10 MB are no longer be extracted or analyzed.
+* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call.
+
+### Bug Fixes
+
+* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias.
diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/javascript/ql/src/codeql-pack.release.yml
+++ b/javascript/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml
index 04ee9ae6135..343d34fce46 100644
--- a/javascript/ql/src/qlpack.yml
+++ b/javascript/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/javascript-queries
-version: 0.7.4-dev
+version: 0.7.4
groups:
- javascript
- queries
diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected
new file mode 100644
index 00000000000..48ecc28df26
--- /dev/null
+++ b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected
@@ -0,0 +1,193 @@
+nodes
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | semmle.label | [FunctionDeclStmt] functio ... } } |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | semmle.order | 1 |
+| tst.js:1:10:1:10 | [VarDecl] g | semmle.label | [VarDecl] g |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.label | [BlockStmt] { u ... } } |
+| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.label | [DeclStmt] using stream = ... |
+| tst.js:2:11:2:16 | [VarDecl] stream | semmle.label | [VarDecl] stream |
+| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.label | [VariableDeclarator] stream ... ource() |
+| tst.js:2:20:2:30 | [VarRef] getResource | semmle.label | [VarRef] getResource |
+| tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() |
+| tst.js:4:5:4:7 | [VarRef] let | semmle.label | [VarRef] let |
+| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.label | [CallExpr] let (test = 20) |
+| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.label | [ExprStmt] let (test = 20); |
+| tst.js:4:10:4:13 | [VarRef] test | semmle.label | [VarRef] test |
+| tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.label | [AssignExpr] test = 20 |
+| tst.js:4:17:4:18 | [Literal] 20 | semmle.label | [Literal] 20 |
+| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.label | [ForStmt] for (us ... ; } |
+| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.label | [DeclStmt] using stream2 = ... |
+| tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.label | [VarDecl] stream2 |
+| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.label | [VariableDeclarator] stream2 ... ource() |
+| tst.js:6:26:6:36 | [VarRef] getResource | semmle.label | [VarRef] getResource |
+| tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() |
+| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } |
+| tst.js:8:9:8:14 | [BreakStmt] break; | semmle.label | [BreakStmt] break; |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | semmle.label | [FunctionDeclStmt] async f ... nd"); } |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | semmle.order | 2 |
+| tst.js:12:16:12:16 | [VarDecl] h | semmle.label | [VarDecl] h |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.label | [BlockStmt] { a ... nd"); } |
+| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.label | [DeclStmt] using stream = ... |
+| tst.js:13:17:13:22 | [VarDecl] stream | semmle.label | [VarDecl] stream |
+| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.label | [VariableDeclarator] stream ... ource() |
+| tst.js:13:26:13:36 | [VarRef] getResource | semmle.label | [VarRef] getResource |
+| tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() |
+| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.label | [ForStmt] for (aw ... ; } |
+| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.label | [DeclStmt] using stream2 = ... |
+| tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.label | [VarDecl] stream2 |
+| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.label | [VariableDeclarator] stream2 ... ource() |
+| tst.js:15:32:15:42 | [VarRef] getResource | semmle.label | [VarRef] getResource |
+| tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() |
+| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } |
+| tst.js:17:9:17:14 | [BreakStmt] break; | semmle.label | [BreakStmt] break; |
+| tst.js:20:5:20:11 | [VarRef] console | semmle.label | [VarRef] console |
+| tst.js:20:5:20:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log |
+| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.label | [MethodCallExpr] console.log("end") |
+| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.label | [ExprStmt] console.log("end"); |
+| tst.js:20:13:20:15 | [Label] log | semmle.label | [Label] log |
+| tst.js:20:17:20:21 | [Literal] "end" | semmle.label | [Literal] "end" |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | semmle.label | [FunctionDeclStmt] functio ... ing); } |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | semmle.order | 3 |
+| tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.label | [VarDecl] usesUsing |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.label | [BlockStmt] { u ... ing); } |
+| tst.js:24:5:24:9 | [VarRef] using | semmle.label | [VarRef] using |
+| tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.label | [CallExpr] using("foo") |
+| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.label | [ExprStmt] using("foo"); |
+| tst.js:24:11:24:15 | [Literal] "foo" | semmle.label | [Literal] "foo" |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.label | [FunctionDeclStmt] functio ... . } |
+| tst.js:25:14:25:18 | [VarDecl] using | semmle.label | [VarDecl] using |
+| tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.label | [SimpleParameter] foo |
+| tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.label | [BlockStmt] { ... . } |
+| tst.js:28:5:28:9 | [VarRef] using | semmle.label | [VarRef] using |
+| tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.label | [CallExpr] using(using) |
+| tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.label | [ExprStmt] using(using); |
+| tst.js:28:11:28:15 | [VarRef] using | semmle.label | [VarRef] using |
+edges
+| file://:0:0:0:0 | (Arguments) | tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.order | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:20:17:20:21 | [Literal] "end" | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:20:17:20:21 | [Literal] "end" | semmle.order | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:24:11:24:15 | [Literal] "foo" | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:24:11:24:15 | [Literal] "foo" | semmle.order | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:28:11:28:15 | [VarRef] using | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.js:28:11:28:15 | [VarRef] using | semmle.order | 0 |
+| file://:0:0:0:0 | (Parameters) | tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.label | 0 |
+| file://:0:0:0:0 | (Parameters) | tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.order | 0 |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:10:1:10 | [VarDecl] g | semmle.label | 0 |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:10:1:10 | [VarDecl] g | semmle.order | 0 |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.label | 5 |
+| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.order | 5 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.label | 1 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.order | 1 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.label | 2 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.order | 2 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.label | 3 |
+| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.order | 3 |
+| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.label | 1 |
+| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.order | 1 |
+| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:11:2:16 | [VarDecl] stream | semmle.label | 1 |
+| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:11:2:16 | [VarDecl] stream | semmle.order | 1 |
+| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.label | 2 |
+| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.order | 2 |
+| tst.js:2:20:2:32 | [CallExpr] getResource() | tst.js:2:20:2:30 | [VarRef] getResource | semmle.label | 0 |
+| tst.js:2:20:2:32 | [CallExpr] getResource() | tst.js:2:20:2:30 | [VarRef] getResource | semmle.order | 0 |
+| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | tst.js:4:5:4:7 | [VarRef] let | semmle.label | 0 |
+| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | tst.js:4:5:4:7 | [VarRef] let | semmle.order | 0 |
+| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.label | 1 |
+| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.order | 1 |
+| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:10:4:13 | [VarRef] test | semmle.label | 1 |
+| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:10:4:13 | [VarRef] test | semmle.order | 1 |
+| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:17:4:18 | [Literal] 20 | semmle.label | 2 |
+| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:17:4:18 | [Literal] 20 | semmle.order | 2 |
+| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.label | 1 |
+| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.order | 1 |
+| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.label | 2 |
+| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.order | 2 |
+| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.label | 1 |
+| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.order | 1 |
+| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.label | 1 |
+| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.order | 1 |
+| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.label | 2 |
+| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.order | 2 |
+| tst.js:6:26:6:38 | [CallExpr] getResource() | tst.js:6:26:6:36 | [VarRef] getResource | semmle.label | 0 |
+| tst.js:6:26:6:38 | [CallExpr] getResource() | tst.js:6:26:6:36 | [VarRef] getResource | semmle.order | 0 |
+| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | tst.js:8:9:8:14 | [BreakStmt] break; | semmle.label | 1 |
+| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | tst.js:8:9:8:14 | [BreakStmt] break; | semmle.order | 1 |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:16:12:16 | [VarDecl] h | semmle.label | 0 |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:16:12:16 | [VarDecl] h | semmle.order | 0 |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.label | 5 |
+| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.order | 5 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.label | 1 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.order | 1 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.label | 2 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.order | 2 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.label | 3 |
+| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.order | 3 |
+| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.label | 1 |
+| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.order | 1 |
+| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:17:13:22 | [VarDecl] stream | semmle.label | 1 |
+| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:17:13:22 | [VarDecl] stream | semmle.order | 1 |
+| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.label | 2 |
+| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.order | 2 |
+| tst.js:13:26:13:38 | [CallExpr] getResource() | tst.js:13:26:13:36 | [VarRef] getResource | semmle.label | 0 |
+| tst.js:13:26:13:38 | [CallExpr] getResource() | tst.js:13:26:13:36 | [VarRef] getResource | semmle.order | 0 |
+| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.label | 1 |
+| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.order | 1 |
+| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.label | 2 |
+| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.order | 2 |
+| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.label | 1 |
+| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.order | 1 |
+| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.label | 1 |
+| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.order | 1 |
+| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.label | 2 |
+| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.order | 2 |
+| tst.js:15:32:15:44 | [CallExpr] getResource() | tst.js:15:32:15:42 | [VarRef] getResource | semmle.label | 0 |
+| tst.js:15:32:15:44 | [CallExpr] getResource() | tst.js:15:32:15:42 | [VarRef] getResource | semmle.order | 0 |
+| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | tst.js:17:9:17:14 | [BreakStmt] break; | semmle.label | 1 |
+| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | tst.js:17:9:17:14 | [BreakStmt] break; | semmle.order | 1 |
+| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:5:20:11 | [VarRef] console | semmle.label | 1 |
+| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:5:20:11 | [VarRef] console | semmle.order | 1 |
+| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:13:20:15 | [Label] log | semmle.label | 2 |
+| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:13:20:15 | [Label] log | semmle.order | 2 |
+| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | tst.js:20:5:20:15 | [DotExpr] console.log | semmle.label | 0 |
+| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | tst.js:20:5:20:15 | [DotExpr] console.log | semmle.order | 0 |
+| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.label | 1 |
+| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.order | 1 |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.label | 0 |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.order | 0 |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.label | 5 |
+| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.order | 5 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.label | 1 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.order | 1 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.label | 2 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.order | 2 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.label | 3 |
+| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.order | 3 |
+| tst.js:24:5:24:16 | [CallExpr] using("foo") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.js:24:5:24:16 | [CallExpr] using("foo") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.js:24:5:24:16 | [CallExpr] using("foo") | tst.js:24:5:24:9 | [VarRef] using | semmle.label | 0 |
+| tst.js:24:5:24:16 | [CallExpr] using("foo") | tst.js:24:5:24:9 | [VarRef] using | semmle.order | 0 |
+| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.label | 1 |
+| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.order | 1 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:14:25:18 | [VarDecl] using | semmle.label | 0 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:14:25:18 | [VarDecl] using | semmle.order | 0 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.label | 5 |
+| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.order | 5 |
+| tst.js:28:5:28:16 | [CallExpr] using(using) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.js:28:5:28:16 | [CallExpr] using(using) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.js:28:5:28:16 | [CallExpr] using(using) | tst.js:28:5:28:9 | [VarRef] using | semmle.label | 0 |
+| tst.js:28:5:28:16 | [CallExpr] using(using) | tst.js:28:5:28:9 | [VarRef] using | semmle.order | 0 |
+| tst.js:28:5:28:17 | [ExprStmt] using(using); | tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.label | 1 |
+| tst.js:28:5:28:17 | [ExprStmt] using(using); | tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.order | 1 |
+graphProperties
+| semmle.graphKind | tree |
diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql
new file mode 100644
index 00000000000..248ea7ad396
--- /dev/null
+++ b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql
@@ -0,0 +1,2 @@
+import javascript
+import semmle.javascript.PrintAst
diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js b/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js
new file mode 100644
index 00000000000..ef5c7f0e679
--- /dev/null
+++ b/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js
@@ -0,0 +1,29 @@
+function g() {
+ using stream = getResource();
+
+ let (test = 20); // <- I didn't know this was a thing
+
+ for (using stream2 = getResource(); ; ) {
+ // ...
+ break;
+ }
+}
+
+async function h() {
+ await using stream = getResource();
+
+ for (await using stream2 = getResource(); ; ) {
+ // ...
+ break;
+ }
+
+ console.log("end");
+}
+
+function usesUsing() {
+ using("foo");
+ function using(foo) {
+ // ...
+ }
+ using(using);
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected
index aead5092430..09fa88a9b37 100644
--- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected
+++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected
@@ -1,3 +1,15 @@
+#select
| tst.tsx:1:10:1:10 | f |
| tst.tsx:1:12:1:12 | o |
| tst.tsx:2:14:2:14 | v |
+| tst.tsx:6:10:6:10 | v |
+| tst.tsx:7:11:7:13 | foo |
+| tst.tsx:9:11:9:13 | bar |
+| tst.tsx:12:16:12:16 | b |
+| tst.tsx:13:17:13:19 | foo |
+consts
+| tst.tsx:2:3:2:26 | const { ... } = o; |
+| tst.tsx:9:5:9:26 | const b ... efined; |
+usings
+| tst.tsx:7:5:7:28 | using f ... as any; |
+| tst.tsx:13:5:13:34 | await u ... as any; |
diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql
index 7039e6fa812..87cbba8b1b4 100644
--- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql
+++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql
@@ -2,3 +2,7 @@ import javascript
from VarDecl decl
select decl
+
+query ConstDeclStmt consts() { any() }
+
+query UsingDeclStmt usings() { any() }
diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx b/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx
index db332181280..8e368671e60 100644
--- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx
+++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx
@@ -2,3 +2,13 @@ function f(o) {
const { p: v = [] } = o;
return v;
}
+
+function v() {
+ using foo = null as any;
+
+ const bar = undefined;
+}
+
+async function b() {
+ await using foo = null as any;
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected
index cd001b3689a..a8406a01260 100644
--- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected
+++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected
@@ -109,6 +109,8 @@ nodes
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
+| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
@@ -151,6 +153,8 @@ nodes
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
+| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
+| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
@@ -1692,8 +1696,56 @@ nodes
| tst.ts:467:15:467:17 | [VarRef] foo | semmle.label | [VarRef] foo |
| tst.ts:467:15:467:20 | [IndexExpr] foo[1] | semmle.label | [IndexExpr] foo[1] |
| tst.ts:467:19:467:19 | [Literal] 1 | semmle.label | [Literal] 1 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | semmle.label | [NamespaceDeclaration] module ... ng>); } |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | semmle.order | 87 |
+| tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.label | [VarDecl] TS52 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.label | [ClassDefinition,TypeDefinition] class S ... ; } |
+| tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.label | [VarDecl] SomeClass |
+| tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
+| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
+| tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
+| tst.ts:473:21:473:20 | [Label] constructor | semmle.label | [Label] constructor |
+| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.label | [Decorator] @((_tar ... => {}) |
+| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.label | [ParExpr] ((_targ ... => {}) |
+| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.label | [ArrowFunctionExpr] (_targe ... ) => {} |
+| tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.label | [SimpleParameter] _target |
+| tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.label | [SimpleParameter] _context |
+| tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
+| tst.ts:475:9:475:11 | [Label] foo | semmle.label | [Label] foo |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.label | [FieldDeclaration] foo = 123; |
+| tst.ts:475:15:475:17 | [Literal] 123 | semmle.label | [Literal] 123 |
+| tst.ts:478:5:478:11 | [VarRef] console | semmle.label | [VarRef] console |
+| tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log |
+| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.label | [MethodCallExpr] console ... adata]) |
+| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.label | [ExprStmt] console ... data]); |
+| tst.ts:478:13:478:15 | [Label] log | semmle.label | [Label] log |
+| tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.label | [VarRef] SomeClass |
+| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.label | [IndexExpr] SomeCla ... tadata] |
+| tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.label | [VarRef] Symbol |
+| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.label | [DotExpr] Symbol.metadata |
+| tst.ts:478:34:478:41 | [Label] metadata | semmle.label | [Label] metadata |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; |
+| tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.label | [Identifier] Pair3 |
+| tst.ts:481:16:481:16 | [Identifier] T | semmle.label | [Identifier] T |
+| tst.ts:481:16:481:16 | [TypeParameter] T | semmle.label | [TypeParameter] T |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.label | [TupleTypeExpr] [first: T, T] |
+| tst.ts:481:22:481:26 | [Identifier] first | semmle.label | [Identifier] first |
+| tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
+| tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
+| tst.ts:483:5:483:11 | [VarRef] console | semmle.label | [VarRef] console |
+| tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log |
+| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.label | [MethodCallExpr] console ... tring>) |
+| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.label | [ExprStmt] console ... ring>); |
+| tst.ts:483:13:483:15 | [Label] log | semmle.label | [Label] log |
+| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.label | [ArrayExpr] ["hello", "world"] |
+| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.label | [SatisfiesExpr] ["hello ... string> |
+| tst.ts:483:18:483:24 | [Literal] "hello" | semmle.label | [Literal] "hello" |
+| tst.ts:483:27:483:33 | [Literal] "world" | semmle.label | [Literal] "world" |
+| tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.label | [LocalTypeAccess] Pair3 |
+| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.label | [GenericTypeExpr] Pair3 |
+| tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
-| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 87 |
+| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 88 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS |
| tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1711,7 +1763,7 @@ nodes
| tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
-| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 88 |
+| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 89 |
| tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES |
| tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1729,7 +1781,7 @@ nodes
| tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
-| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 89 |
+| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 90 |
| tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' |
@@ -1737,7 +1789,7 @@ nodes
| tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; |
| tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
-| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 90 |
+| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 91 |
| tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' |
@@ -1745,7 +1797,7 @@ nodes
| tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; |
| tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
-| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 91 |
+| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 92 |
| tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' |
@@ -1753,16 +1805,16 @@ nodes
| tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; |
| tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; |
-| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 92 |
+| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 93 |
| type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B |
| type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... |
-| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 93 |
+| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 94 |
| type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b |
| type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B |
| type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; |
-| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 94 |
+| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 95 |
| type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray |
| type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T |
| type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T |
@@ -1774,14 +1826,14 @@ nodes
| type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray |
| type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... |
-| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 95 |
+| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 96 |
| type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> |
| type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray |
| type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray |
| type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; |
-| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 96 |
+| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 97 |
| type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json |
| type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] |
| type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -1797,12 +1849,12 @@ nodes
| type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... |
-| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 97 |
+| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 98 |
| type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json |
| type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json |
| type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; |
-| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 98 |
+| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 99 |
| type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode |
| type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] |
| type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -1818,7 +1870,7 @@ nodes
| type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
| type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... |
-| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 99 |
+| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 100 |
| type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode |
| type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] |
| type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
@@ -1843,12 +1895,12 @@ nodes
| type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" |
| type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
-| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 100 |
+| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 101 |
| type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} |
-| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 101 |
+| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 102 |
| type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} |
| type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
@@ -1856,36 +1908,36 @@ nodes
| type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
| type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... |
-| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 102 |
+| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 103 |
| type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj |
| type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C |
| type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} |
-| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 103 |
+| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 104 |
| type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} |
| type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... |
-| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 104 |
+| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 105 |
| type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj |
| type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E |
| type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} |
-| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 105 |
+| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 106 |
| type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} |
| type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N |
| type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... |
-| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 106 |
+| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 107 |
| type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj |
| type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N |
| type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
-| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 107 |
+| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 108 |
| type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } |
-| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 108 |
+| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 109 |
| type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I |
| type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S |
| type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S |
@@ -1893,14 +1945,14 @@ nodes
| type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; |
| type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... |
-| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 109 |
+| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 110 |
| type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i |
| type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I | semmle.label | [VariableDeclarator] i: I |
| type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I |
| type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I | semmle.label | [GenericTypeExpr] I |
| type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } |
-| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 110 |
+| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 111 |
| type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
| type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
@@ -1912,14 +1964,14 @@ nodes
| type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T |
| type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... |
-| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 111 |
+| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 112 |
| type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C | semmle.label | [VariableDeclarator] c: C |
| type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C |
| type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C | semmle.label | [GenericTypeExpr] C |
| type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } |
-| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 112 |
+| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 113 |
| type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color |
| type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red |
| type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red |
@@ -1928,29 +1980,29 @@ nodes
| type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue |
| type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... |
-| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 113 |
+| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 114 |
| type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color |
| type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color |
| type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } |
-| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 114 |
+| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 115 |
| type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember |
| type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member |
| type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... |
-| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 115 |
+| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 116 |
| type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e |
| type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember |
| type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; |
-| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 116 |
+| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 117 |
| type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias |
| type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T |
| type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T |
| type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... |
-| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 117 |
+| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 118 |
| type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray |
| type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> |
| type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias |
@@ -2129,6 +2181,10 @@ edges
| file://:0:0:0:0 | (Arguments) | tst.ts:460:26:460:31 | [Literal] "John" | semmle.order | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:465:35:465:49 | [ArrayExpr] ["a", "b" ,"c"] | semmle.label | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:465:35:465:49 | [ArrayExpr] ["a", "b" ,"c"] | semmle.order | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.order | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.label | 0 |
+| file://:0:0:0:0 | (Arguments) | tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:28:14:28 | [SimpleParameter] y | semmle.label | 1 |
@@ -2223,6 +2279,10 @@ edges
| file://:0:0:0:0 | (Parameters) | tst.ts:449:21:449:24 | [SimpleParameter] name | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:462:75:462:78 | [SimpleParameter] args | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:462:75:462:78 | [SimpleParameter] args | semmle.order | 0 |
+| file://:0:0:0:0 | (Parameters) | tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.label | 0 |
+| file://:0:0:0:0 | (Parameters) | tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.order | 0 |
+| file://:0:0:0:0 | (Parameters) | tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.label | 1 |
+| file://:0:0:0:0 | (Parameters) | tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.order | 1 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:21:19:21:21 | [SimpleParameter] key | semmle.label | 0 |
@@ -2253,6 +2313,8 @@ edges
| file://:0:0:0:0 | (TypeParameters) | tst.ts:431:53:431:58 | [TypeParameter] Return | semmle.order | 2 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:462:40:462:72 | [TypeParameter] const T ... tring[] | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:462:40:462:72 | [TypeParameter] const T ... tring[] | semmle.order | 0 |
+| file://:0:0:0:0 | (TypeParameters) | tst.ts:481:16:481:16 | [TypeParameter] T | semmle.label | 0 |
+| file://:0:0:0:0 | (TypeParameters) | tst.ts:481:16:481:16 | [TypeParameter] T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | 0 |
@@ -4999,6 +5061,96 @@ edges
| tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:15:467:17 | [VarRef] foo | semmle.order | 1 |
| tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:19:467:19 | [Literal] 1 | semmle.label | 2 |
| tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:19:467:19 | [Literal] 1 | semmle.order | 2 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.label | 1 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.order | 1 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.label | 2 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.order | 2 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.label | 3 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.order | 3 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.label | 4 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.order | 4 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.label | 5 |
+| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.order | 5 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.label | 1 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.order | 1 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.label | 3 |
+| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.order | 3 |
+| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.label | 2 |
+| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.order | 2 |
+| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [Label] constructor | semmle.label | 1 |
+| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [Label] constructor | semmle.order | 1 |
+| tst.ts:473:21:473:20 | [FunctionExpr] () {} | tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.label | 5 |
+| tst.ts:473:21:473:20 | [FunctionExpr] () {} | tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.order | 5 |
+| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.label | 1 |
+| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.order | 1 |
+| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.label | 1 |
+| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.order | 1 |
+| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | file://:0:0:0:0 | (Parameters) | semmle.label | 1 |
+| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | file://:0:0:0:0 | (Parameters) | semmle.order | 1 |
+| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.label | 5 |
+| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.order | 5 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.label | 1 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.order | 1 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:9:475:11 | [Label] foo | semmle.label | 2 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:9:475:11 | [Label] foo | semmle.order | 2 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:15:475:17 | [Literal] 123 | semmle.label | 3 |
+| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:15:475:17 | [Literal] 123 | semmle.order | 3 |
+| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:5:478:11 | [VarRef] console | semmle.label | 1 |
+| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:5:478:11 | [VarRef] console | semmle.order | 1 |
+| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:13:478:15 | [Label] log | semmle.label | 2 |
+| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:13:478:15 | [Label] log | semmle.order | 2 |
+| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.label | 0 |
+| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.order | 0 |
+| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.label | 1 |
+| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.order | 1 |
+| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.label | 1 |
+| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.order | 1 |
+| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.label | 2 |
+| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.order | 2 |
+| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.label | 1 |
+| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.order | 1 |
+| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:34:478:41 | [Label] metadata | semmle.label | 2 |
+| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:34:478:41 | [Label] metadata | semmle.order | 2 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | file://:0:0:0:0 | (TypeParameters) | semmle.label | -100 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | file://:0:0:0:0 | (TypeParameters) | semmle.order | -100 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.label | 1 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.order | 1 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.label | 3 |
+| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.order | 3 |
+| tst.ts:481:16:481:16 | [TypeParameter] T | tst.ts:481:16:481:16 | [Identifier] T | semmle.label | 1 |
+| tst.ts:481:16:481:16 | [TypeParameter] T | tst.ts:481:16:481:16 | [Identifier] T | semmle.order | 1 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:22:481:26 | [Identifier] first | semmle.label | 1 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:22:481:26 | [Identifier] first | semmle.order | 1 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.label | 2 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.order | 2 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.label | 3 |
+| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.order | 3 |
+| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:5:483:11 | [VarRef] console | semmle.label | 1 |
+| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:5:483:11 | [VarRef] console | semmle.order | 1 |
+| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:13:483:15 | [Label] log | semmle.label | 2 |
+| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:13:483:15 | [Label] log | semmle.order | 2 |
+| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
+| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
+| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.label | 0 |
+| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.order | 0 |
+| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.label | 1 |
+| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.order | 1 |
+| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:18:483:24 | [Literal] "hello" | semmle.label | 1 |
+| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:18:483:24 | [Literal] "hello" | semmle.order | 1 |
+| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:27:483:33 | [Literal] "world" | semmle.label | 2 |
+| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:27:483:33 | [Literal] "world" | semmle.order | 2 |
+| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.label | 1 |
+| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.order | 1 |
+| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.label | 2 |
+| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.order | 2 |
+| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.label | 1 |
+| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.order | 1 |
+| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.label | 2 |
+| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.order | 2 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 |
diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected
index 206a634640e..e31ed6be412 100644
--- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected
+++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected
@@ -633,6 +633,31 @@ getExprType
| tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] |
| tst.ts:467:15:467:20 | foo[1] | "b" |
| tst.ts:467:19:467:19 | 1 | 1 |
+| tst.ts:472:8:472:11 | TS52 | typeof TS52 in library-tests/TypeScript/Types/tst.ts |
+| tst.ts:473:11:473:19 | SomeClass | SomeClass |
+| tst.ts:474:10:474:36 | ((_targ ... => {}) | (_target: undefined, _context: ClassFieldDecora... |
+| tst.ts:474:11:474:35 | (_targe ... ) => {} | (_target: undefined, _context: ClassFieldDecora... |
+| tst.ts:474:12:474:18 | _target | undefined |
+| tst.ts:474:21:474:28 | _context | ClassFieldDecoratorContext &... |
+| tst.ts:475:9:475:11 | foo | number |
+| tst.ts:475:15:475:17 | 123 | 123 |
+| tst.ts:478:5:478:11 | console | Console |
+| tst.ts:478:5:478:15 | console.log | (...data: any[]) => void |
+| tst.ts:478:5:478:43 | console ... adata]) | void |
+| tst.ts:478:13:478:15 | log | (...data: any[]) => void |
+| tst.ts:478:17:478:25 | SomeClass | typeof SomeClass in tst.ts:472 |
+| tst.ts:478:17:478:42 | SomeCla ... tadata] | DecoratorMetadataObject |
+| tst.ts:478:27:478:32 | Symbol | SymbolConstructor |
+| tst.ts:478:27:478:41 | Symbol.metadata | typeof metadata |
+| tst.ts:478:34:478:41 | metadata | typeof metadata |
+| tst.ts:483:5:483:11 | console | Console |
+| tst.ts:483:5:483:15 | console.log | (...data: any[]) => void |
+| tst.ts:483:5:483:59 | console ... tring>) | void |
+| tst.ts:483:13:483:15 | log | (...data: any[]) => void |
+| tst.ts:483:17:483:34 | ["hello", "world"] | Pair3 |
+| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] |
+| tst.ts:483:18:483:24 | "hello" | "hello" |
+| tst.ts:483:27:483:33 | "world" | "world" |
| tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" |
| tstModuleCJS.cts:2:12:2:15 | Math | Math |
| tstModuleCJS.cts:2:12:2:22 | Math.random | () => number |
@@ -744,6 +769,8 @@ getTypeDefinitionType
| tst.ts:408:3:410:3 | interfa ... er;\\n } | HSVObj |
| tst.ts:419:3:425:3 | class P ... }\\n } | Person |
| tst.ts:447:5:458:5 | class P ... }\\n } | Person |
+| tst.ts:473:5:476:5 | class S ... ;\\n } | SomeClass |
+| tst.ts:481:5:481:34 | type Pa ... T, T]; | Pair3 |
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
| type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray |
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
@@ -1093,6 +1120,15 @@ getTypeExprType
| tst.ts:462:65:462:72 | string[] | readonly string[] |
| tst.ts:462:81:462:81 | T | T |
| tst.ts:462:85:462:85 | T | T |
+| tst.ts:481:10:481:14 | Pair3 | Pair3 |
+| tst.ts:481:16:481:16 | T | T |
+| tst.ts:481:21:481:33 | [first: T, T] | [first: T, T] |
+| tst.ts:481:22:481:26 | first | any |
+| tst.ts:481:29:481:29 | T | T |
+| tst.ts:481:32:481:32 | T | T |
+| tst.ts:483:46:483:50 | Pair3 | Pair3 |
+| tst.ts:483:46:483:58 | Pair3 | Pair3 |
+| tst.ts:483:52:483:57 | string | string |
| tstModuleCJS.cts:1:33:1:35 | 'a' | "a" |
| tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" |
| tstModuleCJS.cts:1:39:1:41 | 'b' | "b" |
@@ -1196,12 +1232,15 @@ referenceDefinition
| MyUnion | tst.ts:65:1:65:54 | type My ... true}; |
| MyUnion2 | tst.ts:68:1:68:49 | type My ... true}; |
| NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} |
+| Pair3 | tst.ts:481:5:481:34 | type Pa ... T, T]; |
+| Pair3 | tst.ts:481:5:481:34 | type Pa ... T, T]; |
| Person | tst.ts:222:3:234:3 | class P ... }\\n } |
| Person | tst.ts:419:3:425:3 | class P ... }\\n } |
| Person | tst.ts:447:5:458:5 | class P ... }\\n } |
| RGB | tst.ts:393:3:393:56 | type RG ... umber]; |
| RGBObj | tst.ts:404:3:406:3 | interfa ... er;\\n } |
| Shape | tst.ts:140:3:142:47 | type Sh ... mber }; |
+| SomeClass | tst.ts:473:5:476:5 | class S ... ;\\n } |
| State | tst.ts:342:1:345:1 | interfa ... void;\\n} |
| State | tst.ts:342:1:345:1 | interfa ... void;\\n} |
| Sub | tst.ts:97:3:101:3 | class S ... }\\n } |
@@ -1275,6 +1314,8 @@ tupleTypes
| tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 0 | "a" | 3 | no-rest |
| tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 1 | "b" | 3 | no-rest |
| tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 2 | "c" | 3 | no-rest |
+| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | 0 | string | 2 | no-rest |
+| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | 1 | string | 2 | no-rest |
unknownType
| tst.ts:40:5:40:15 | unknownType | unknown |
| tst.ts:47:8:47:8 | e | unknown |
@@ -1355,6 +1396,7 @@ unionIndex
| number | 1 | string \| number |
| number | 1 | string \| number \| boolean |
| number | 1 | string \| number \| boolean \| { [property: string... |
+| number | 1 | string \| number \| symbol |
| number | 1 | string \| number \| true |
| string | 0 | VirtualNode \| { [key: string]: any; } |
| string | 0 | string \| Error |
@@ -1363,10 +1405,12 @@ unionIndex
| string | 0 | string \| number |
| string | 0 | string \| number \| boolean |
| string | 0 | string \| number \| boolean \| { [property: string... |
+| string | 0 | string \| number \| symbol |
| string | 0 | string \| number \| true |
| string | 0 | string \| symbol |
| string | 0 | string \| { [key: string]: any; } |
| symbol | 1 | string \| symbol |
+| symbol | 2 | string \| number \| symbol |
| true | 1 | boolean |
| true | 1 | boolean \| Promise |
| true | 2 | number \| boolean |
diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts
index aafe82aeb13..27ee7357c36 100644
--- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts
+++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts
@@ -465,4 +465,20 @@ module TS50 {
const foo = myConstIdFunction(["a", "b" ,"c"]);
const b = foo[1]; // <- "b"
+}
+
+/////////////////
+
+module TS52 {
+ class SomeClass {
+ @((_target, _context) => {})
+ foo = 123;
+ }
+
+ console.log(SomeClass[Symbol.metadata]); // <- has type DecoratorMetadataObject
+
+ // named and anonymous tuple elements.
+ type Pair3 = [first: T, T];
+
+ console.log(["hello", "world"] satisfies Pair3);
}
\ No newline at end of file
diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py
index 47a6bec76ab..1e03b426e7b 100755
--- a/misc/scripts/accept-expected-changes-from-ci.py
+++ b/misc/scripts/accept-expected-changes-from-ci.py
@@ -114,7 +114,7 @@ def make_patches_from_log_file(log_file_lines) -> List[Patch]:
while True:
next_line = parse_log_line(next(lines))
# it can be the case that
- if next_line[0] in (" ", "-", "+", "@"):
+ if next_line and next_line[0] in (" ", "-", "+", "@"):
lines_changed.append(next_line)
if "FAILED" in next_line:
break
diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md
index 0abf0d49317..ab0e65b02b1 100644
--- a/misc/suite-helpers/CHANGELOG.md
+++ b/misc/suite-helpers/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.4
+
+No user-facing changes.
+
## 0.6.3
No user-facing changes.
diff --git a/misc/suite-helpers/change-notes/released/0.6.4.md b/misc/suite-helpers/change-notes/released/0.6.4.md
new file mode 100644
index 00000000000..7e98b0159fc
--- /dev/null
+++ b/misc/suite-helpers/change-notes/released/0.6.4.md
@@ -0,0 +1,3 @@
+## 0.6.4
+
+No user-facing changes.
diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml
index b7dafe32c5d..ced8cf94614 100644
--- a/misc/suite-helpers/codeql-pack.release.yml
+++ b/misc/suite-helpers/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.6.3
+lastReleaseVersion: 0.6.4
diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml
index 0c423deb64d..79c9cad4f4e 100644
--- a/misc/suite-helpers/qlpack.yml
+++ b/misc/suite-helpers/qlpack.yml
@@ -1,4 +1,4 @@
name: codeql/suite-helpers
-version: 0.6.4-dev
+version: 0.6.4
groups: shared
warnOnImplicitThis: true
diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md
index d3b291f4b48..fcef91e98a4 100644
--- a/python/ql/lib/CHANGELOG.md
+++ b/python/ql/lib/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.10.4
+
+### Minor Analysis Improvements
+
+* Regular expressions containing multiple parse mode flags are now interpretted correctly. For example `"(?is)abc.*"` with both the `i` and `s` flags.
+* Added `shlex.quote` as a sanitizer for the `py/shell-command-constructed-from-input` query.
+
## 0.10.3
### Minor Analysis Improvements
diff --git a/python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md b/python/ql/lib/change-notes/released/0.10.4.md
similarity index 52%
rename from python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md
rename to python/ql/lib/change-notes/released/0.10.4.md
index 2d676227491..7f93237c621 100644
--- a/python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md
+++ b/python/ql/lib/change-notes/released/0.10.4.md
@@ -1,4 +1,6 @@
----
-category: minorAnalysis
----
+## 0.10.4
+
+### Minor Analysis Improvements
+
* Regular expressions containing multiple parse mode flags are now interpretted correctly. For example `"(?is)abc.*"` with both the `i` and `s` flags.
+* Added `shlex.quote` as a sanitizer for the `py/shell-command-constructed-from-input` query.
diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml
index c6c21ef7d6c..0e1088e51a9 100644
--- a/python/ql/lib/codeql-pack.release.yml
+++ b/python/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.10.3
+lastReleaseVersion: 0.10.4
diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml
index cac5d51e2e4..bb4f49e84e8 100644
--- a/python/ql/lib/qlpack.yml
+++ b/python/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/python-all
-version: 0.10.4-dev
+version: 0.10.4
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python
diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll
index e154491f795..2513a4aa3bd 100644
--- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll
+++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll
@@ -3,297 +3,50 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import python
+private import DataFlowImplSpecific
+private import TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
+private module Input implements InputSig {
+ private import Private
+ private import Public
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
+ predicate argHasPostUpdateExclude(ArgumentNode n) {
+ exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isStarArgs(_))
or
- none()
+ exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat())
}
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
+ predicate reverseReadExclude(Node n) {
+ // since `self`/`cls` parameters can be marked as implicit argument to `super()`,
+ // they will have PostUpdateNodes. We have a read-step from the synthetic `**kwargs`
+ // parameter, but dataflow-consistency queries should _not_ complain about there not
+ // being a post-update node for the synthetic `**kwargs` parameter.
+ n instanceof SynthDictSplatParameterNode
}
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
+ predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
+ // For normal parameters that can both be passed as positional arguments or keyword
+ // arguments, we currently have parameter positions for both cases..
+ //
+ // TODO: Figure out how bad breaking this consistency check is
+ exists(Function func, Parameter param |
+ c.getScope() = func and
+ p = parameterNode(param) and
+ c.getParameter(pos) = p and
+ param = func.getArg(_) and
+ param = func.getArgByName(_)
)
}
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
+ predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
+ not exists(call.getLocation().getFile().getRelativePath())
}
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
+ predicate identityLocalStepExclude(Node n) {
+ not exists(n.getLocation().getFile().getRelativePath())
}
}
+
+module Consistency = MakeConsistency;
diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll
index 390c9738cc3..a39ffc27e87 100644
--- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.TaintTracking
private import CommandInjectionCustomizations::CommandInjection as CommandInjection
private import semmle.python.Concepts as Concepts
+private import semmle.python.ApiGraphs
/**
* Module containing sources, sinks, and sanitizers for shell command constructed from library input.
@@ -17,6 +18,9 @@ module UnsafeShellCommandConstruction {
/** A source for shell command constructed from library input vulnerabilities. */
abstract class Source extends DataFlow::Node { }
+ /** A sanitizer for shell command constructed from library input vulnerabilities. */
+ abstract class Sanitizer extends DataFlow::Node { }
+
private import semmle.python.frameworks.Setuptools
/** An input parameter to a gem seen as a source. */
@@ -156,4 +160,13 @@ module UnsafeShellCommandConstruction {
override DataFlow::Node getStringConstruction() { result = formatCall }
}
+
+ /**
+ * A call to `shlex.quote`, considered as a sanitizer.
+ */
+ class ShlexQuoteAsSanitizer extends Sanitizer, DataFlow::Node {
+ ShlexQuoteAsSanitizer() {
+ this = API::moduleImport("shlex").getMember("quote").getACall().getArg(0)
+ }
+ }
}
diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll
index 0d9ebb8a472..80781a97ac6 100644
--- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll
@@ -24,7 +24,8 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) {
- node instanceof CommandInjection::Sanitizer // using all sanitizers from `rb/command-injection`
+ node instanceof Sanitizer or
+ node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection`
}
// override to require the path doesn't have unmatched return steps
diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md
index d8bc409ff86..2cd732792f6 100644
--- a/python/ql/src/CHANGELOG.md
+++ b/python/ql/src/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.8.4
+
+### Minor Analysis Improvements
+
+* Improved _Reflected server-side cross-site scripting_ (`py/reflective-xss`) query to not alert on data passed to `flask.jsonify`. Since these HTTP responses are returned with mime-type `application/json`, they do not pose a security risk for XSS.
+* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand.
+
## 0.8.3
No user-facing changes.
diff --git a/python/ql/src/change-notes/2023-08-17-improved-path-graph.md b/python/ql/src/change-notes/2023-08-17-improved-path-graph.md
deleted file mode 100644
index a2545d362e9..00000000000
--- a/python/ql/src/change-notes/2023-08-17-improved-path-graph.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand.
diff --git a/python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md b/python/ql/src/change-notes/released/0.8.4.md
similarity index 56%
rename from python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md
rename to python/ql/src/change-notes/released/0.8.4.md
index 8268f296606..223f2a83361 100644
--- a/python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md
+++ b/python/ql/src/change-notes/released/0.8.4.md
@@ -1,4 +1,6 @@
----
-category: minorAnalysis
----
+## 0.8.4
+
+### Minor Analysis Improvements
+
* Improved _Reflected server-side cross-site scripting_ (`py/reflective-xss`) query to not alert on data passed to `flask.jsonify`. Since these HTTP responses are returned with mime-type `application/json`, they do not pose a security risk for XSS.
+* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand.
diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml
index b6e46394f37..32eff3dc9f3 100644
--- a/python/ql/src/codeql-pack.release.yml
+++ b/python/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.8.3
+lastReleaseVersion: 0.8.4
diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml
index f7ff3ff2348..37fb0ca7969 100644
--- a/python/ql/src/qlpack.yml
+++ b/python/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/python-queries
-version: 0.8.4-dev
+version: 0.8.4
groups:
- python
- queries
diff --git a/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll b/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll
index fd56070f86b..76ddc3643f1 100644
--- a/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll
+++ b/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll
@@ -1,46 +1,6 @@
+// TODO: this should be promoted to be a REAL consistency query by being placed in
+// `python/ql/consistency-queries`. For for now it resides here.
import python
import semmle.python.dataflow.new.DataFlow::DataFlow
import semmle.python.dataflow.new.internal.DataFlowPrivate
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
-
-// TODO: this should be promoted to be a REAL consistency query by being placed in
-// `python/ql/consistency-queries`. For for now it resides here.
-private class MyConsistencyConfiguration extends ConsistencyConfiguration {
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
- exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isStarArgs(_))
- or
- exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat())
- }
-
- override predicate reverseReadExclude(Node n) {
- // since `self`/`cls` parameters can be marked as implicit argument to `super()`,
- // they will have PostUpdateNodes. We have a read-step from the synthetic `**kwargs`
- // parameter, but dataflow-consistency queries should _not_ complain about there not
- // being a post-update node for the synthetic `**kwargs` parameter.
- n instanceof SynthDictSplatParameterNode
- }
-
- override predicate uniqueParameterNodePositionExclude(
- DataFlowCallable c, ParameterPosition pos, Node p
- ) {
- // For normal parameters that can both be passed as positional arguments or keyword
- // arguments, we currently have parameter positions for both cases..
- //
- // TODO: Figure out how bad breaking this consistency check is
- exists(Function func, Parameter param |
- c.getScope() = func and
- p = parameterNode(param) and
- c.getParameter(pos) = p and
- param = func.getArg(_) and
- param = func.getArgByName(_)
- )
- }
-
- override predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
- not exists(call.getLocation().getFile().getRelativePath())
- }
-
- override predicate identityLocalStepExclude(Node n) {
- not exists(n.getLocation().getFile().getRelativePath())
- }
-}
diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py
index 1b4bc708c45..f491b93583d 100644
--- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py
+++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py
@@ -46,4 +46,8 @@ def subprocess_flag (name):
subprocess.Popen("ping " + name, shell=unknownValue) # OK - shell assumed to be False
def intentional(command):
- os.system("fish -ic " + command) # $result=OK - intentional
\ No newline at end of file
+ os.system("fish -ic " + command) # $result=OK - intentional
+
+import shlex
+def unsafe_shell_sanitized(name):
+ os.system("ping " + shlex.quote(name)) # $result=OK - sanitized
\ No newline at end of file
diff --git a/ql/Cargo.lock b/ql/Cargo.lock
index c6d82f879f3..8d97ef2bcac 100644
Binary files a/ql/Cargo.lock and b/ql/Cargo.lock differ
diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml
index 0f70891bade..2e3a662303a 100644
--- a/ql/buramu/Cargo.toml
+++ b/ql/buramu/Cargo.toml
@@ -7,6 +7,6 @@ edition = "2018"
[dependencies]
lazy_static = "1.4.0"
-chrono = "0.4.27"
+chrono = "0.4.28"
rayon = "1.7.0"
-regex = "1.9.3"
+regex = "1.9.5"
diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml
index f082d00f6f0..b90fc7ff61e 100644
--- a/ql/extractor/Cargo.toml
+++ b/ql/extractor/Cargo.toml
@@ -16,5 +16,5 @@ clap = { version = "4.2", features = ["derive"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
rayon = "1.7.0"
-regex = "1.9.3"
+regex = "1.9.5"
codeql-extractor = { path = "../../shared/tree-sitter-extractor" }
diff --git a/ruby/ql/consistency-queries/DataFlowConsistency.ql b/ruby/ql/consistency-queries/DataFlowConsistency.ql
index 46384305f7a..6cf0fe9a282 100644
--- a/ruby/ql/consistency-queries/DataFlowConsistency.ql
+++ b/ruby/ql/consistency-queries/DataFlowConsistency.ql
@@ -1,13 +1,16 @@
-import codeql.ruby.AST
-import codeql.ruby.CFG
-import codeql.ruby.DataFlow::DataFlow
-import codeql.ruby.dataflow.internal.DataFlowPrivate
-import codeql.ruby.dataflow.internal.DataFlowImplConsistency::Consistency
+import codeql.ruby.DataFlow::DataFlow as DataFlow
+private import codeql.ruby.AST
+private import codeql.ruby.CFG
+private import codeql.ruby.dataflow.internal.DataFlowImplSpecific
+private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-private class MyConsistencyConfiguration extends ConsistencyConfiguration {
- override predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode }
+private module Input implements InputSig {
+ private import RubyDataFlow
- override predicate argHasPostUpdateExclude(ArgumentNode n) {
+ predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode }
+
+ predicate argHasPostUpdateExclude(ArgumentNode n) {
n instanceof BlockArgumentNode
or
n instanceof FlowSummaryNode
@@ -17,7 +20,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
not isNonConstantExpr(getAPostUpdateNodeForArg(n.asExpr()))
}
- override predicate postHasUniquePreExclude(PostUpdateNode n) {
+ predicate postHasUniquePreExclude(PostUpdateNode n) {
exists(CfgNodes::ExprCfgNode e, CfgNodes::ExprCfgNode arg |
e = getAPostUpdateNodeForArg(arg) and
e != arg and
@@ -25,7 +28,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
)
}
- override predicate uniquePostUpdateExclude(Node n) {
+ predicate uniquePostUpdateExclude(Node n) {
exists(CfgNodes::ExprCfgNode e, CfgNodes::ExprCfgNode arg |
e = getAPostUpdateNodeForArg(arg) and
e != arg and
@@ -34,7 +37,9 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
}
}
-query predicate multipleToString(Node n, string s) {
+import MakeConsistency
+
+query predicate multipleToString(DataFlow::Node n, string s) {
s = strictconcat(n.toString(), ",") and
strictcount(n.toString()) > 1
}
diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md
index ae92859730f..c9c03626ec3 100644
--- a/ruby/ql/lib/CHANGELOG.md
+++ b/ruby/ql/lib/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.7.4
+
+No user-facing changes.
+
## 0.7.3
### Minor Analysis Improvements
diff --git a/ruby/ql/lib/change-notes/released/0.7.4.md b/ruby/ql/lib/change-notes/released/0.7.4.md
new file mode 100644
index 00000000000..1b33df9cb1e
--- /dev/null
+++ b/ruby/ql/lib/change-notes/released/0.7.4.md
@@ -0,0 +1,3 @@
+## 0.7.4
+
+No user-facing changes.
diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/ruby/ql/lib/codeql-pack.release.yml
+++ b/ruby/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll b/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll
index 9a386369e91..3ff85f5553d 100644
--- a/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll
+++ b/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll
@@ -73,16 +73,14 @@ module SuccessorTypes {
}
/**
- * A conditional control flow successor. Either a Boolean successor (`BooleanSuccessor`),
- * an emptiness successor (`EmptinessSuccessor`), or a matching successor
- * (`MatchingSuccessor`)
+ * A conditional control flow successor. Either a Boolean successor (`BooleanSuccessor`)
+ * or a matching successor (`MatchingSuccessor`)
*/
class ConditionalSuccessor extends SuccessorType {
boolean value;
ConditionalSuccessor() {
this = CfgImpl::TBooleanSuccessor(value) or
- this = CfgImpl::TEmptinessSuccessor(value) or
this = CfgImpl::TMatchingSuccessor(value)
}
@@ -109,41 +107,6 @@ module SuccessorTypes {
*/
class BooleanSuccessor extends ConditionalSuccessor, CfgImpl::TBooleanSuccessor { }
- /**
- * An emptiness control flow successor.
- *
- * For example, this program fragment:
- *
- * ```rb
- * for arg in args do
- * puts arg
- * end
- * puts "done";
- * ```
- *
- * has a control flow graph containing emptiness successors:
- *
- * ```
- * args
- * |
- * for------<-----
- * / \ \
- * / \ |
- * / \ |
- * / \ |
- * empty non-empty |
- * | \ |
- * puts "done" \ |
- * arg |
- * | |
- * puts arg |
- * \___/
- * ```
- */
- class EmptinessSuccessor extends ConditionalSuccessor, CfgImpl::TEmptinessSuccessor {
- override string toString() { if value = true then result = "empty" else result = "non-empty" }
- }
-
/**
* A matching control flow successor.
*
diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll
index c7a3b27afc8..0aa93e573eb 100644
--- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll
+++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll
@@ -1513,7 +1513,6 @@ private module Cached {
newtype TSuccessorType =
TSuccessorSuccessor() or
TBooleanSuccessor(boolean b) { b in [false, true] } or
- TEmptinessSuccessor(boolean isEmpty) { isEmpty in [false, true] } or
TMatchingSuccessor(boolean isMatch) { isMatch in [false, true] } or
TReturnSuccessor() or
TBreakSuccessor() or
diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll
deleted file mode 100644
index e154491f795..00000000000
--- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * Provides consistency queries for checking invariants in the language-specific
- * data-flow classes and predicates.
- */
-
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
-
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
-
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
- or
- none()
- }
-
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
- }
-
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
- )
- }
-
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
- }
-
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
- }
-}
diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml
index e50377dfb13..7f512644e8d 100644
--- a/ruby/ql/lib/qlpack.yml
+++ b/ruby/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/ruby-all
-version: 0.7.4-dev
+version: 0.7.4
groups: ruby
extractor: ruby
dbscheme: ruby.dbscheme
diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md
index 9e85e2317d3..2bc373cd332 100644
--- a/ruby/ql/src/CHANGELOG.md
+++ b/ruby/ql/src/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.7.4
+
+### New Queries
+
+* Added a new experimental query, `rb/improper-ldap-auth`, to detect cases where user input is used during LDAP authentication without proper validation or sanitization, potentially leading to authentication bypass.
+
## 0.7.3
No user-facing changes.
diff --git a/ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md b/ruby/ql/src/change-notes/released/0.7.4.md
similarity index 88%
rename from ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md
rename to ruby/ql/src/change-notes/released/0.7.4.md
index 13c5a89c808..228683b8a68 100644
--- a/ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md
+++ b/ruby/ql/src/change-notes/released/0.7.4.md
@@ -1,4 +1,5 @@
----
-category: newQuery
----
+## 0.7.4
+
+### New Queries
+
* Added a new experimental query, `rb/improper-ldap-auth`, to detect cases where user input is used during LDAP authentication without proper validation or sanitization, potentially leading to authentication bypass.
diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml
index a4ea9c8de17..e388f34b4ec 100644
--- a/ruby/ql/src/codeql-pack.release.yml
+++ b/ruby/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.7.3
+lastReleaseVersion: 0.7.4
diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml
index 441effac827..92a6a245e19 100644
--- a/ruby/ql/src/qlpack.yml
+++ b/ruby/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/ruby-queries
-version: 0.7.4-dev
+version: 0.7.4
groups:
- ruby
- queries
diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md
index aab63b11f75..b6f5cd028e2 100644
--- a/shared/controlflow/CHANGELOG.md
+++ b/shared/controlflow/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.3
+
+No user-facing changes.
+
## 0.0.2
No user-facing changes.
diff --git a/shared/controlflow/change-notes/released/0.0.3.md b/shared/controlflow/change-notes/released/0.0.3.md
new file mode 100644
index 00000000000..af7864fc7d5
--- /dev/null
+++ b/shared/controlflow/change-notes/released/0.0.3.md
@@ -0,0 +1,3 @@
+## 0.0.3
+
+No user-facing changes.
diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml
index 55dc06fbd76..a24b693d1e7 100644
--- a/shared/controlflow/codeql-pack.release.yml
+++ b/shared/controlflow/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.0.2
+lastReleaseVersion: 0.0.3
diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml
index 90520957d85..08806425df6 100644
--- a/shared/controlflow/qlpack.yml
+++ b/shared/controlflow/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/controlflow
-version: 0.0.3-dev
+version: 0.0.3
groups: shared
library: true
dependencies:
diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md
index 1a5f4d38663..7ab03105cb7 100644
--- a/shared/dataflow/CHANGELOG.md
+++ b/shared/dataflow/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.0.3
+
+### New Features
+
+* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack.
+
+### Minor Analysis Improvements
+
+* The shared taint-tracking library is now part of the dataflow qlpack.
+
## 0.0.2
### Major Analysis Improvements
diff --git a/shared/dataflow/change-notes/2023-08-04-taint-tracking.md b/shared/dataflow/change-notes/2023-08-04-taint-tracking.md
deleted file mode 100644
index 000d7ea265c..00000000000
--- a/shared/dataflow/change-notes/2023-08-04-taint-tracking.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The shared taint-tracking library is now part of the dataflow qlpack.
diff --git a/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md b/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md
deleted file mode 100644
index 4f879df3fd3..00000000000
--- a/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: feature
----
-* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack.
diff --git a/shared/dataflow/change-notes/released/0.0.3.md b/shared/dataflow/change-notes/released/0.0.3.md
new file mode 100644
index 00000000000..4b6ac03adc1
--- /dev/null
+++ b/shared/dataflow/change-notes/released/0.0.3.md
@@ -0,0 +1,9 @@
+## 0.0.3
+
+### New Features
+
+* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack.
+
+### Minor Analysis Improvements
+
+* The shared taint-tracking library is now part of the dataflow qlpack.
diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml
index 55dc06fbd76..a24b693d1e7 100644
--- a/shared/dataflow/codeql-pack.release.yml
+++ b/shared/dataflow/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.0.2
+lastReleaseVersion: 0.0.3
diff --git a/shared/dataflow/codeql/dataflow/VariableCapture.qll b/shared/dataflow/codeql/dataflow/VariableCapture.qll
index c94e06b8731..4a68f0563bc 100644
--- a/shared/dataflow/codeql/dataflow/VariableCapture.qll
+++ b/shared/dataflow/codeql/dataflow/VariableCapture.qll
@@ -95,9 +95,6 @@ signature module InputSig {
/** Gets the variable that is the target of this write. */
CapturedVariable getVariable();
- /** Gets the expression that is the source of this write. */
- Expr getSource();
-
/** Gets the location of this write. */
Location getLocation();
@@ -210,6 +207,22 @@ signature module OutputSig {
I::ClosureExpr getClosureExpr();
}
+ /**
+ * A node representing the incoming value about to be written at the given assignment.
+ *
+ * The captured-variable library will generate flows out of this node, and assume that other
+ * parts of the language implementation produce the relevant data flows into this node.
+ *
+ * For ordinary assignments, this could be mapped to the right-hand side of the assignment.
+ *
+ * For more general cases, where an lvalue has no direct corresponding rvalue, this can be mapped
+ * to a data-flow node that wraps the lvalue, with language-specific incoming data flows.
+ */
+ class VariableWriteSourceNode extends ClosureNode {
+ /** Gets the variable write for which this node is the incoming value being written to the variable. */
+ I::VariableWrite getVariableWrite();
+ }
+
/** Holds if `post` is a `PostUpdateNode` for `pre`. */
predicate capturePostUpdateNode(SynthesizedCaptureNode post, SynthesizedCaptureNode pre);
@@ -239,7 +252,6 @@ module Flow implements OutputSig {
private class RelevantExpr extends FinalExpr {
RelevantExpr() {
this instanceof VariableRead or
- any(VariableWrite vw).getSource() = this or
this instanceof ClosureExpr or
any(ClosureExpr ce).hasAliasedAccess(this)
}
@@ -353,14 +365,6 @@ module Flow implements OutputSig {
query predicate uniqueWriteTarget(string msg) { uniqueWriteTarget(_, msg) }
- private predicate uniqueWriteSource(VariableWrite vw, string msg) {
- msg = "VariableWrite has no source expression" and not exists(vw.getSource())
- or
- msg = "VariableWrite has multiple source expressions" and 2 <= strictcount(vw.getSource())
- }
-
- query predicate uniqueWriteSource(string msg) { uniqueWriteSource(_, msg) }
-
private predicate uniqueWriteCfgNode(VariableWrite vw, string msg) {
msg = "VariableWrite has no cfg node" and not vw.hasCfgNode(_, _)
or
@@ -370,17 +374,6 @@ module Flow implements OutputSig {
query predicate uniqueWriteCfgNode(string msg) { uniqueWriteCfgNode(_, msg) }
- private predicate localWriteStep(VariableWrite vw, string msg) {
- exists(BasicBlock bb1, BasicBlock bb2 |
- vw.hasCfgNode(bb1, _) and
- vw.getSource().hasCfgNode(bb2, _) and
- bb1.getEnclosingCallable() != bb2.getEnclosingCallable() and
- msg = "VariableWrite is not a local step"
- )
- }
-
- query predicate localWriteStep(string msg) { localWriteStep(_, msg) }
-
query predicate uniqueReadVariable(VariableRead vr, string msg) {
msg = "VariableRead has no source variable" and not exists(vr.getVariable())
or
@@ -436,9 +429,7 @@ module Flow implements OutputSig {
n = strictcount(Expr e | uniqueLocation(e, msg)) or
n = strictcount(Expr e | uniqueCfgNode(e, msg)) or
n = strictcount(VariableWrite vw | uniqueWriteTarget(vw, msg)) or
- n = strictcount(VariableWrite vw | uniqueWriteSource(vw, msg)) or
n = strictcount(VariableWrite vw | uniqueWriteCfgNode(vw, msg)) or
- n = strictcount(VariableWrite vw | localWriteStep(vw, msg)) or
n = strictcount(VariableRead vr | uniqueReadVariable(vr, msg)) or
n = strictcount(ClosureExpr ce | closureMustHaveBody(ce, msg)) or
n = strictcount(ClosureExpr ce, Expr access | closureAliasMustBeInSameScope(ce, access, msg)) or
@@ -719,13 +710,12 @@ module Flow implements OutputSig {
TExprNode(Expr expr, boolean isPost) {
expr instanceof VariableRead and isPost = [false, true]
or
- exists(VariableWrite vw | expr = vw.getSource() and isPost = false)
- or
synthRead(_, _, _, _, expr) and isPost = [false, true]
} or
TParamNode(CapturedParameter p) or
TThisParamNode(Callable c) { captureAccess(_, c) } or
- TMallocNode(ClosureExpr ce) { hasConstructorCapture(ce, _) }
+ TMallocNode(ClosureExpr ce) { hasConstructorCapture(ce, _) } or
+ TVariableWriteSourceNode(VariableWrite write)
class ClosureNode extends TClosureNode {
/** Gets a textual representation of this node. */
@@ -751,6 +741,11 @@ module Flow implements OutputSig {
result = "this" and this = TThisParamNode(_)
or
result = "malloc" and this = TMallocNode(_)
+ or
+ exists(VariableWrite write |
+ this = TVariableWriteSourceNode(write) and
+ result = "Source of write to " + write.getVariable().toString()
+ )
}
/** Gets the location of this node. */
@@ -778,6 +773,10 @@ module Flow implements OutputSig {
exists(Callable c | this = TThisParamNode(c) and result = c.getLocation())
or
exists(ClosureExpr ce | this = TMallocNode(ce) and result = ce.getLocation())
+ or
+ exists(VariableWrite write |
+ this = TVariableWriteSourceNode(write) and result = write.getLocation()
+ )
}
}
@@ -837,6 +836,10 @@ module Flow implements OutputSig {
ClosureExpr getClosureExpr() { this = TMallocNode(result) }
}
+ class VariableWriteSourceNode extends ClosureNode, TVariableWriteSourceNode {
+ VariableWrite getVariableWrite() { this = TVariableWriteSourceNode(result) }
+ }
+
predicate capturePostUpdateNode(SynthesizedCaptureNode post, SynthesizedCaptureNode pre) {
exists(CapturedVariable v, BasicBlock bb, int i |
pre = TSynthRead(v, bb, i, false) and post = TSynthRead(v, bb, i, true)
@@ -881,7 +884,7 @@ module Flow implements OutputSig {
or
exists(VariableWrite vw, CapturedVariable v |
captureWrite(v, bb, i, true, vw) and
- n = TExprNode(vw.getSource(), false) and
+ n = TVariableWriteSourceNode(vw) and
isPost = false and
cc = TVariable(v)
)
@@ -928,7 +931,7 @@ module Flow implements OutputSig {
// write to v inside the closure body
exists(BasicBlock bb, int i, VariableWrite vw |
captureWrite(v, bb, i, false, vw) and
- node1 = TExprNode(vw.getSource(), false) and
+ node1 = TVariableWriteSourceNode(vw) and
node2 = TSynthThisQualifier(bb, i, true)
)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll
similarity index 60%
rename from csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll
rename to shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll
index e154491f795..a24f8ab794a 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll
+++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll
@@ -3,67 +3,73 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import codeql.dataflow.DataFlow as DF
+private import codeql.dataflow.TaintTracking as TT
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
+signature module InputSig {
+ /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
+ default predicate uniqueEnclosingCallableExclude(DataFlowLang::Node n) { none() }
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
+ /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
+ default predicate uniqueCallEnclosingCallableExclude(DataFlowLang::DataFlowCall call) { none() }
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
+ default predicate uniqueNodeLocationExclude(DataFlowLang::Node n) { none() }
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
+ /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
+ default predicate missingLocationExclude(DataFlowLang::Node n) { none() }
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
+ default predicate postWithInFlowExclude(DataFlowLang::Node n) { none() }
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
+ default predicate argHasPostUpdateExclude(DataFlowLang::ArgumentNode n) { none() }
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
+ default predicate reverseReadExclude(DataFlowLang::Node n) { none() }
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
+ default predicate postHasUniquePreExclude(DataFlowLang::PostUpdateNode n) { none() }
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
+ /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
+ default predicate uniquePostUpdateExclude(DataFlowLang::Node n) { none() }
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
+ /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
+ default predicate viableImplInCallContextTooLargeExclude(
+ DataFlowLang::DataFlowCall call, DataFlowLang::DataFlowCall ctx,
+ DataFlowLang::DataFlowCallable callable
+ ) {
+ none()
}
- private class RelevantNode extends Node {
+ /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
+ default predicate uniqueParameterNodeAtPositionExclude(
+ DataFlowLang::DataFlowCallable c, DataFlowLang::ParameterPosition pos, DataFlowLang::Node p
+ ) {
+ none()
+ }
+
+ /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
+ default predicate uniqueParameterNodePositionExclude(
+ DataFlowLang::DataFlowCallable c, DataFlowLang::ParameterPosition pos, DataFlowLang::Node p
+ ) {
+ none()
+ }
+
+ /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
+ default predicate identityLocalStepExclude(DataFlowLang::Node n) { none() }
+}
+
+module MakeConsistency<
+ DF::InputSig DataFlowLang, TT::InputSig TaintTrackingLang,
+ InputSig Input>
+{
+ private import DataFlowLang
+ private import TaintTrackingLang
+
+ final private class NodeFinal = Node;
+
+ private class RelevantNode extends NodeFinal {
RelevantNode() {
this instanceof ArgumentNode or
this instanceof ParameterNode or
@@ -87,7 +93,7 @@ module Consistency {
n instanceof RelevantNode and
c = count(nodeGetEnclosingCallable(n)) and
c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
+ not Input::uniqueEnclosingCallableExclude(n) and
msg = "Node should have one enclosing callable but has " + c + "."
)
}
@@ -96,7 +102,7 @@ module Consistency {
exists(int c |
c = count(call.getEnclosingCallable()) and
c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
+ not Input::uniqueCallEnclosingCallableExclude(call) and
msg = "Call should have one enclosing callable but has " + c + "."
)
}
@@ -117,7 +123,7 @@ module Consistency {
n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
) and
c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
+ not Input::uniqueNodeLocationExclude(n) and
msg = "Node should have one location but has " + c + "."
)
}
@@ -127,7 +133,7 @@ module Consistency {
c =
strictcount(Node n |
not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
+ not Input::missingLocationExclude(n)
) and
msg = "Nodes without location: " + c
)
@@ -193,28 +199,19 @@ module Consistency {
n = getAnOutNode(call, _) and
msg = "OutNode and call does not share enclosing callable."
or
- n.(ArgumentNode).argumentOf(call, _) and
+ isArgumentNode(n, call, _) and
msg = "ArgumentNode and call does not share enclosing callable."
) and
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
}
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
- or
- none()
- }
-
query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
+ n = n.getPreUpdateNode() and
msg = "PostUpdateNode should not equal its pre-update node."
}
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
+ not Input::postHasUniquePreExclude(n) and
exists(int c |
c = count(n.getPreUpdateNode()) and
c != 1 and
@@ -223,7 +220,7 @@ module Consistency {
}
query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
+ not Input::uniquePostUpdateExclude(n) and
1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
msg = "Node has multiple PostUpdateNodes."
}
@@ -237,26 +234,20 @@ module Consistency {
query predicate reverseRead(Node n, string msg) {
exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
+ not Input::reverseReadExclude(n) and
msg = "Origin of readStep is missing a PostUpdateNode."
}
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
+ not Input::argHasPostUpdateExclude(n) and
msg = "ArgumentNode is missing PostUpdateNode."
}
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
+ query predicate postWithInFlow(PostUpdateNode n, string msg) {
not clearsContent(n, _) and
simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
+ not Input::postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
@@ -265,13 +256,13 @@ module Consistency {
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
+ not Input::viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
query predicate uniqueParameterNodeAtPosition(
DataFlowCallable c, ParameterPosition pos, Node p, string msg
) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
+ not Input::uniqueParameterNodeAtPositionExclude(c, pos, p) and
isParameterNode(p, c, pos) and
not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
msg = "Parameters with overlapping positions."
@@ -280,7 +271,7 @@ module Consistency {
query predicate uniqueParameterNodePosition(
DataFlowCallable c, ParameterPosition pos, Node p, string msg
) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
+ not Input::uniqueParameterNodePositionExclude(c, pos, p) and
isParameterNode(p, c, pos) and
not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
msg = "Parameter node with multiple positions."
@@ -293,7 +284,7 @@ module Consistency {
query predicate identityLocalStep(Node n, string msg) {
simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
+ not Input::identityLocalStepExclude(n) and
msg = "Node steps to itself"
}
}
diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml
index 62a35f1ccc8..0a15dee3ec6 100644
--- a/shared/dataflow/qlpack.yml
+++ b/shared/dataflow/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/dataflow
-version: 0.0.3-dev
+version: 0.0.3
groups: shared
library: true
dependencies:
diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md
index 4c7b7dd6878..2bfa7916b94 100644
--- a/shared/mad/CHANGELOG.md
+++ b/shared/mad/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/mad/change-notes/released/0.1.4.md b/shared/mad/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/mad/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/mad/codeql-pack.release.yml
+++ b/shared/mad/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml
index cf6c9c6ea7d..711f69baef6 100644
--- a/shared/mad/qlpack.yml
+++ b/shared/mad/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/mad
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
dependencies:
diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md
index 8cd409f9735..bcf4cdb469c 100644
--- a/shared/regex/CHANGELOG.md
+++ b/shared/regex/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/regex/change-notes/released/0.1.4.md b/shared/regex/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/regex/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/regex/codeql-pack.release.yml
+++ b/shared/regex/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml
index a30e17c4d96..9ae2aebd903 100644
--- a/shared/regex/qlpack.yml
+++ b/shared/regex/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/regex
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
dependencies:
diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md
index 466f3f45326..175ecab1b6e 100644
--- a/shared/ssa/CHANGELOG.md
+++ b/shared/ssa/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/ssa/change-notes/released/0.1.4.md b/shared/ssa/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/ssa/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/ssa/codeql-pack.release.yml
+++ b/shared/ssa/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml
index 0db56594e86..22ca03d8047 100644
--- a/shared/ssa/qlpack.yml
+++ b/shared/ssa/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/ssa
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
warnOnImplicitThis: true
diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md
index 0474ebe6865..01c61a97e76 100644
--- a/shared/tutorial/CHANGELOG.md
+++ b/shared/tutorial/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/tutorial/change-notes/released/0.1.4.md b/shared/tutorial/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/tutorial/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/tutorial/codeql-pack.release.yml
+++ b/shared/tutorial/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml
index 4beadd85122..520077ea1d5 100644
--- a/shared/tutorial/qlpack.yml
+++ b/shared/tutorial/qlpack.yml
@@ -1,6 +1,6 @@
name: codeql/tutorial
description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries.
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
warnOnImplicitThis: true
diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md
index ee0d1b59186..6a11a27cd0c 100644
--- a/shared/typetracking/CHANGELOG.md
+++ b/shared/typetracking/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/typetracking/change-notes/released/0.1.4.md b/shared/typetracking/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/typetracking/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/typetracking/codeql-pack.release.yml
+++ b/shared/typetracking/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml
index 3505e8f33f1..e50be8d7635 100644
--- a/shared/typetracking/qlpack.yml
+++ b/shared/typetracking/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/typetracking
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
dependencies:
diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md
index a8f556aa029..675cc520f94 100644
--- a/shared/typos/CHANGELOG.md
+++ b/shared/typos/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/typos/change-notes/released/0.1.4.md b/shared/typos/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/typos/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/typos/codeql-pack.release.yml
+++ b/shared/typos/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml
index ec757b0242c..2c8585faa48 100644
--- a/shared/typos/qlpack.yml
+++ b/shared/typos/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/typos
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
warnOnImplicitThis: true
diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md
index cf58b4ea37c..b42b17238e5 100644
--- a/shared/util/CHANGELOG.md
+++ b/shared/util/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
No user-facing changes.
diff --git a/shared/util/change-notes/released/0.1.4.md b/shared/util/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/util/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/util/codeql-pack.release.yml
+++ b/shared/util/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml
index 24020172913..75eb3bf288a 100644
--- a/shared/util/qlpack.yml
+++ b/shared/util/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/util
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
dependencies:
diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md
index e41dc84c7c8..72ed00d14e3 100644
--- a/shared/yaml/CHANGELOG.md
+++ b/shared/yaml/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.4
+
+No user-facing changes.
+
## 0.1.3
### New Features
diff --git a/shared/yaml/change-notes/released/0.1.4.md b/shared/yaml/change-notes/released/0.1.4.md
new file mode 100644
index 00000000000..a77c429adba
--- /dev/null
+++ b/shared/yaml/change-notes/released/0.1.4.md
@@ -0,0 +1,3 @@
+## 0.1.4
+
+No user-facing changes.
diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml
index b79d8f9d00a..e8ee3af8ef9 100644
--- a/shared/yaml/codeql-pack.release.yml
+++ b/shared/yaml/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.3
+lastReleaseVersion: 0.1.4
diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml
index 58627ae3db8..e68ccfec57d 100644
--- a/shared/yaml/qlpack.yml
+++ b/shared/yaml/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/yaml
-version: 0.1.4-dev
+version: 0.1.4
groups: shared
library: true
warnOnImplicitThis: true
diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel
index 83dff3f8033..57b828ef350 100644
--- a/swift/BUILD.bazel
+++ b/swift/BUILD.bazel
@@ -1,4 +1,4 @@
-load("@rules_pkg//:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files", "strip_prefix")
+load("@rules_pkg//:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix")
load("@rules_pkg//:install.bzl", "pkg_install")
load("//:defs.bzl", "codeql_platform")
load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles")
@@ -57,8 +57,8 @@ pkg_filegroup(
)
pkg_runfiles(
- name = "xcode-autobuilder",
- srcs = ["//swift/xcode-autobuilder"],
+ name = "swift-autobuilder",
+ srcs = ["//swift/swift-autobuilder"],
prefix = "tools/" + codeql_platform,
)
@@ -93,7 +93,7 @@ pkg_filegroup(
],
}) + select({
"@platforms//os:macos": [
- ":xcode-autobuilder",
+ ":swift-autobuilder",
],
"//conditions:default": [
":diagnostics",
@@ -130,7 +130,7 @@ generate_cmake(
"//swift/logging/tests/assertion-diagnostics:assert-false",
] + select({
"@platforms//os:linux": ["//swift/tools/diagnostics:autobuilder-incompatible-os"],
- "@platforms//os:macos": ["//swift/xcode-autobuilder"],
+ "@platforms//os:macos": ["//swift/swift-autobuilder"],
}),
visibility = ["//visibility:public"],
)
diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp
index 22c0c7bf797..3274c49675e 100644
--- a/swift/extractor/translators/ExprTranslator.cpp
+++ b/swift/extractor/translators/ExprTranslator.cpp
@@ -460,7 +460,17 @@ codeql::UnresolvedMemberExpr ExprTranslator::translateUnresolvedMemberExpr(
codeql::SequenceExpr ExprTranslator::translateSequenceExpr(const swift::SequenceExpr& expr) {
auto entry = createExprEntry(expr);
- entry.elements = dispatcher.fetchRepeatedLabels(expr.getElements());
+ // SequenceExpr represents a flat tree of expressions with elements at odd indices being the
+ // parents of the elements with even indices, so we only extract the "parent" elements here. In
+ // case there is a single child, we extract it as a parent. See
+ // https://github.com/github/codeql/pull/14119 and commit message for more details.
+ if (expr.getNumElements() == 1) {
+ entry.elements = dispatcher.fetchRepeatedLabels(expr.getElements());
+ } else {
+ for (int i = 1; i < expr.getNumElements(); i += 2) {
+ entry.elements.emplace_back(dispatcher.fetchLabel(expr.getElement(i)));
+ }
+ }
return entry;
}
diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md
index ad443f621cb..b59991858c6 100644
--- a/swift/ql/lib/CHANGELOG.md
+++ b/swift/ql/lib/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.2.4
+
+### Minor Analysis Improvements
+
+* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library.
+* Added flow models of collection `.withContiguous[Mutable]StorageIfAvailable`, `.withUnsafe[Mutable]BufferPointer` and `.withUnsafe[Mutable]Bytes` methods.
+
## 0.2.3
### Major Analysis Improvements
diff --git a/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md b/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md
deleted file mode 100644
index 9e2d3bd0e25..00000000000
--- a/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-category: minorAnalysis
----
-
-* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library.
diff --git a/swift/ql/lib/change-notes/2023-08-04-closure-models.md b/swift/ql/lib/change-notes/released/0.2.4.md
similarity index 50%
rename from swift/ql/lib/change-notes/2023-08-04-closure-models.md
rename to swift/ql/lib/change-notes/released/0.2.4.md
index ba655f59774..b7e6c5dcc0f 100644
--- a/swift/ql/lib/change-notes/2023-08-04-closure-models.md
+++ b/swift/ql/lib/change-notes/released/0.2.4.md
@@ -1,5 +1,6 @@
----
-category: minorAnalysis
----
+## 0.2.4
+### Minor Analysis Improvements
+
+* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library.
* Added flow models of collection `.withContiguous[Mutable]StorageIfAvailable`, `.withUnsafe[Mutable]BufferPointer` and `.withUnsafe[Mutable]Bytes` methods.
diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml
index 0b605901b42..7f1e3841dcd 100644
--- a/swift/ql/lib/codeql-pack.release.yml
+++ b/swift/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.2.3
+lastReleaseVersion: 0.2.4
diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll
index e154491f795..e9de11852a6 100644
--- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll
+++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll
@@ -3,297 +3,11 @@
* data-flow classes and predicates.
*/
-private import DataFlowImplSpecific::Private
-private import DataFlowImplSpecific::Public
-private import tainttracking1.TaintTrackingParameter::Private
-private import tainttracking1.TaintTrackingParameter::Public
+private import swift
+private import DataFlowImplSpecific
+private import TaintTrackingImplSpecific
+private import codeql.dataflow.internal.DataFlowImplConsistency
-module Consistency {
- private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
+private module Input implements InputSig { }
- /** A class for configuring the consistency queries. */
- class ConsistencyConfiguration extends TConsistencyConfiguration {
- string toString() { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
- predicate uniqueEnclosingCallableExclude(Node n) { none() }
-
- /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
- predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
- predicate uniqueNodeLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `missingLocation`. */
- predicate missingLocationExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
- predicate postWithInFlowExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
- predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `reverseRead`. */
- predicate reverseReadExclude(Node n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
- predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
-
- /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
- predicate uniquePostUpdateExclude(Node n) { none() }
-
- /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
- predicate viableImplInCallContextTooLargeExclude(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
- predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
- predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
- none()
- }
-
- /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
- predicate identityLocalStepExclude(Node n) { none() }
- }
-
- private class RelevantNode extends Node {
- RelevantNode() {
- this instanceof ArgumentNode or
- this instanceof ParameterNode or
- this instanceof ReturnNode or
- this = getAnOutNode(_, _) or
- simpleLocalFlowStep(this, _) or
- simpleLocalFlowStep(_, this) or
- jumpStep(this, _) or
- jumpStep(_, this) or
- storeStep(this, _, _) or
- storeStep(_, _, this) or
- readStep(this, _, _) or
- readStep(_, _, this) or
- defaultAdditionalTaintStep(this, _) or
- defaultAdditionalTaintStep(_, this)
- }
- }
-
- query predicate uniqueEnclosingCallable(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(nodeGetEnclosingCallable(n)) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
- msg = "Node should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
- exists(int c |
- c = count(call.getEnclosingCallable()) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
- msg = "Call should have one enclosing callable but has " + c + "."
- )
- }
-
- query predicate uniqueType(Node n, string msg) {
- exists(int c |
- n instanceof RelevantNode and
- c = count(getNodeType(n)) and
- c != 1 and
- msg = "Node should have one type but has " + c + "."
- )
- }
-
- query predicate uniqueNodeLocation(Node n, string msg) {
- exists(int c |
- c =
- count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- ) and
- c != 1 and
- not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
- msg = "Node should have one location but has " + c + "."
- )
- }
-
- query predicate missingLocation(string msg) {
- exists(int c |
- c =
- strictcount(Node n |
- not n.hasLocationInfo(_, _, _, _, _) and
- not any(ConsistencyConfiguration conf).missingLocationExclude(n)
- ) and
- msg = "Nodes without location: " + c
- )
- }
-
- query predicate uniqueNodeToString(Node n, string msg) {
- exists(int c |
- c = count(n.toString()) and
- c != 1 and
- msg = "Node should have one toString but has " + c + "."
- )
- }
-
- query predicate missingToString(string msg) {
- exists(int c |
- c = strictcount(Node n | not exists(n.toString())) and
- msg = "Nodes without toString: " + c
- )
- }
-
- query predicate parameterCallable(ParameterNode p, string msg) {
- exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
- msg = "Callable mismatch for parameter."
- }
-
- query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
- simpleLocalFlowStep(n1, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Local flow step does not preserve enclosing callable."
- }
-
- query predicate readStepIsLocal(Node n1, Node n2, string msg) {
- readStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Read step does not preserve enclosing callable."
- }
-
- query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
- storeStep(n1, _, n2) and
- nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
- msg = "Store step does not preserve enclosing callable."
- }
-
- private DataFlowType typeRepr() { result = getNodeType(_) }
-
- query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
- t = typeRepr() and
- not compatibleTypes(t, t) and
- msg = "Type compatibility predicate is not reflexive."
- }
-
- query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
- isUnreachableInCall(n, call) and
- exists(DataFlowCallable c |
- c = nodeGetEnclosingCallable(n) and
- not viableCallable(call) = c
- ) and
- msg = "Call context for isUnreachableInCall is inconsistent with call graph."
- }
-
- query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
- (
- n = getAnOutNode(call, _) and
- msg = "OutNode and call does not share enclosing callable."
- or
- n.(ArgumentNode).argumentOf(call, _) and
- msg = "ArgumentNode and call does not share enclosing callable."
- ) and
- nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a result of `getPreUpdateNode` to be an
- // instance of `PostUpdateNode`.
- private Node getPre(PostUpdateNode n) {
- result = n.getPreUpdateNode()
- or
- none()
- }
-
- query predicate postIsNotPre(PostUpdateNode n, string msg) {
- getPre(n) = n and
- msg = "PostUpdateNode should not equal its pre-update node."
- }
-
- query predicate postHasUniquePre(PostUpdateNode n, string msg) {
- not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
- exists(int c |
- c = count(n.getPreUpdateNode()) and
- c != 1 and
- msg = "PostUpdateNode should have one pre-update node but has " + c + "."
- )
- }
-
- query predicate uniquePostUpdate(Node n, string msg) {
- not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
- 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
- msg = "Node has multiple PostUpdateNodes."
- }
-
- query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
- nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
- msg = "PostUpdateNode does not share callable with its pre-update node."
- }
-
- private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
-
- query predicate reverseRead(Node n, string msg) {
- exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
- not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
- msg = "Origin of readStep is missing a PostUpdateNode."
- }
-
- query predicate argHasPostUpdate(ArgumentNode n, string msg) {
- not hasPost(n) and
- not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
- msg = "ArgumentNode is missing PostUpdateNode."
- }
-
- // This predicate helps the compiler forget that in some languages
- // it is impossible for a `PostUpdateNode` to be the target of
- // `simpleLocalFlowStep`.
- private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
-
- query predicate postWithInFlow(Node n, string msg) {
- isPostUpdateNode(n) and
- not clearsContent(n, _) and
- simpleLocalFlowStep(_, n) and
- not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
- msg = "PostUpdateNode should not be the target of local flow."
- }
-
- query predicate viableImplInCallContextTooLarge(
- DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
- ) {
- callable = viableImplInCallContext(call, ctx) and
- not callable = viableCallable(call) and
- not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
- }
-
- query predicate uniqueParameterNodeAtPosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
- msg = "Parameters with overlapping positions."
- }
-
- query predicate uniqueParameterNodePosition(
- DataFlowCallable c, ParameterPosition pos, Node p, string msg
- ) {
- not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
- isParameterNode(p, c, pos) and
- not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
- msg = "Parameter node with multiple positions."
- }
-
- query predicate uniqueContentApprox(Content c, string msg) {
- not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
- msg = "Non-unique content approximation."
- }
-
- query predicate identityLocalStep(Node n, string msg) {
- simpleLocalFlowStep(n, n) and
- not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
- msg = "Node steps to itself"
- }
-}
+module Consistency = MakeConsistency;
diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml
index cd9b209ffae..b079f1b600d 100644
--- a/swift/ql/lib/qlpack.yml
+++ b/swift/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/swift-all
-version: 0.2.4-dev
+version: 0.2.4
groups: swift
extractor: swift
dbscheme: swift.dbscheme
diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md
index 71fec278599..7f1e54070bc 100644
--- a/swift/ql/src/CHANGELOG.md
+++ b/swift/ql/src/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.2.4
+
+### New Queries
+
+* Added new query "Incomplete regular expression for hostnames" (`swift/incomplete-hostname-regexp`). This query finds regular expressions matching a URL or hostname that may match more hostnames than expected.
+
## 0.2.3
No user-facing changes.
diff --git a/swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md b/swift/ql/src/change-notes/released/0.2.4.md
similarity index 88%
rename from swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md
rename to swift/ql/src/change-notes/released/0.2.4.md
index d70dfce16f7..12170e4fdf6 100644
--- a/swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md
+++ b/swift/ql/src/change-notes/released/0.2.4.md
@@ -1,5 +1,5 @@
----
-category: newQuery
----
+## 0.2.4
+
+### New Queries
* Added new query "Incomplete regular expression for hostnames" (`swift/incomplete-hostname-regexp`). This query finds regular expressions matching a URL or hostname that may match more hostnames than expected.
diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml
index 0b605901b42..7f1e3841dcd 100644
--- a/swift/ql/src/codeql-pack.release.yml
+++ b/swift/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.2.3
+lastReleaseVersion: 0.2.4
diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml
index 87c3fb14701..96c455c5ce8 100644
--- a/swift/ql/src/qlpack.yml
+++ b/swift/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/swift-queries
-version: 0.2.4-dev
+version: 0.2.4
groups:
- swift
- queries
diff --git a/swift/xcode-autobuilder/BUILD.bazel b/swift/swift-autobuilder/BUILD.bazel
similarity index 92%
rename from swift/xcode-autobuilder/BUILD.bazel
rename to swift/swift-autobuilder/BUILD.bazel
index 13d6e9818ff..951b0c243f2 100644
--- a/swift/xcode-autobuilder/BUILD.bazel
+++ b/swift/swift-autobuilder/BUILD.bazel
@@ -1,7 +1,7 @@
load("//swift:rules.bzl", "swift_cc_binary")
swift_cc_binary(
- name = "xcode-autobuilder",
+ name = "swift-autobuilder",
srcs = glob([
"*.cpp",
"*.h",
diff --git a/swift/xcode-autobuilder/XcodeBuildRunner.cpp b/swift/swift-autobuilder/BuildRunner.cpp
similarity index 97%
rename from swift/xcode-autobuilder/XcodeBuildRunner.cpp
rename to swift/swift-autobuilder/BuildRunner.cpp
index 831d7e1f94e..cf0521bf789 100644
--- a/swift/xcode-autobuilder/XcodeBuildRunner.cpp
+++ b/swift/swift-autobuilder/BuildRunner.cpp
@@ -1,4 +1,4 @@
-#include "swift/xcode-autobuilder/XcodeBuildRunner.h"
+#include "swift/swift-autobuilder/BuildRunner.h"
#include
#include
@@ -6,7 +6,7 @@
#include "absl/strings/str_join.h"
#include "swift/logging/SwiftLogging.h"
-#include "swift/xcode-autobuilder/CustomizingBuildLink.h"
+#include "swift/swift-autobuilder/CustomizingBuildLink.h"
constexpr codeql::SwiftDiagnostic buildCommandFailed{
.id = "build-command-failed",
diff --git a/swift/xcode-autobuilder/XcodeBuildRunner.h b/swift/swift-autobuilder/BuildRunner.h
similarity index 70%
rename from swift/xcode-autobuilder/XcodeBuildRunner.h
rename to swift/swift-autobuilder/BuildRunner.h
index ab86a00c767..404e74d4319 100644
--- a/swift/xcode-autobuilder/XcodeBuildRunner.h
+++ b/swift/swift-autobuilder/BuildRunner.h
@@ -1,7 +1,7 @@
#pragma once
-#include "swift/xcode-autobuilder/XcodeTarget.h"
-#include "swift/xcode-autobuilder/XcodeProjectParser.h"
+#include "swift/swift-autobuilder/XcodeTarget.h"
+#include "swift/swift-autobuilder/ProjectParser.h"
#include
void installDependencies(const ProjectStructure& target, bool dryRun);
diff --git a/swift/xcode-autobuilder/CFHelpers.cpp b/swift/swift-autobuilder/CFHelpers.cpp
similarity index 95%
rename from swift/xcode-autobuilder/CFHelpers.cpp
rename to swift/swift-autobuilder/CFHelpers.cpp
index 7ca19c7b2b2..aba37e982dc 100644
--- a/swift/xcode-autobuilder/CFHelpers.cpp
+++ b/swift/swift-autobuilder/CFHelpers.cpp
@@ -1,4 +1,4 @@
-#include "swift/xcode-autobuilder/CFHelpers.h"
+#include "swift/swift-autobuilder/CFHelpers.h"
#include
diff --git a/swift/xcode-autobuilder/CFHelpers.h b/swift/swift-autobuilder/CFHelpers.h
similarity index 100%
rename from swift/xcode-autobuilder/CFHelpers.h
rename to swift/swift-autobuilder/CFHelpers.h
diff --git a/swift/xcode-autobuilder/CustomizingBuildLink.h b/swift/swift-autobuilder/CustomizingBuildLink.h
similarity index 100%
rename from swift/xcode-autobuilder/CustomizingBuildLink.h
rename to swift/swift-autobuilder/CustomizingBuildLink.h
diff --git a/swift/xcode-autobuilder/XcodeProjectParser.cpp b/swift/swift-autobuilder/ProjectParser.cpp
similarity index 98%
rename from swift/xcode-autobuilder/XcodeProjectParser.cpp
rename to swift/swift-autobuilder/ProjectParser.cpp
index 072bcaeeee2..fce29e5b70b 100644
--- a/swift/xcode-autobuilder/XcodeProjectParser.cpp
+++ b/swift/swift-autobuilder/ProjectParser.cpp
@@ -1,4 +1,4 @@
-#include "swift/xcode-autobuilder/XcodeProjectParser.h"
+#include "swift/swift-autobuilder/ProjectParser.h"
#include
#include
@@ -8,8 +8,8 @@
#include
#include
-#include "swift/xcode-autobuilder/XcodeWorkspaceParser.h"
-#include "swift/xcode-autobuilder/CFHelpers.h"
+#include "swift/swift-autobuilder/XcodeWorkspaceParser.h"
+#include "swift/swift-autobuilder/CFHelpers.h"
namespace fs = std::filesystem;
diff --git a/swift/xcode-autobuilder/XcodeProjectParser.h b/swift/swift-autobuilder/ProjectParser.h
similarity index 90%
rename from swift/xcode-autobuilder/XcodeProjectParser.h
rename to swift/swift-autobuilder/ProjectParser.h
index 56958f2b97e..d7e9cdb5eb9 100644
--- a/swift/xcode-autobuilder/XcodeProjectParser.h
+++ b/swift/swift-autobuilder/ProjectParser.h
@@ -1,6 +1,6 @@
#pragma once
-#include "swift/xcode-autobuilder/XcodeTarget.h"
+#include "swift/swift-autobuilder/XcodeTarget.h"
#include
#include
#include
diff --git a/swift/xcode-autobuilder/XcodeTarget.h b/swift/swift-autobuilder/XcodeTarget.h
similarity index 100%
rename from swift/xcode-autobuilder/XcodeTarget.h
rename to swift/swift-autobuilder/XcodeTarget.h
diff --git a/swift/xcode-autobuilder/XcodeWorkspaceParser.cpp b/swift/swift-autobuilder/XcodeWorkspaceParser.cpp
similarity index 96%
rename from swift/xcode-autobuilder/XcodeWorkspaceParser.cpp
rename to swift/swift-autobuilder/XcodeWorkspaceParser.cpp
index c315ba3831b..8fd9fee7a2e 100644
--- a/swift/xcode-autobuilder/XcodeWorkspaceParser.cpp
+++ b/swift/swift-autobuilder/XcodeWorkspaceParser.cpp
@@ -1,7 +1,7 @@
#include
#include
#include
-#include "swift/xcode-autobuilder/XcodeWorkspaceParser.h"
+#include "swift/swift-autobuilder/XcodeWorkspaceParser.h"
/*
Extracts FileRef locations from an XML of the following form:
diff --git a/swift/xcode-autobuilder/XcodeWorkspaceParser.h b/swift/swift-autobuilder/XcodeWorkspaceParser.h
similarity index 100%
rename from swift/xcode-autobuilder/XcodeWorkspaceParser.h
rename to swift/swift-autobuilder/XcodeWorkspaceParser.h
diff --git a/swift/xcode-autobuilder/xcode-autobuilder.cpp b/swift/swift-autobuilder/swift-autobuilder.cpp
similarity index 92%
rename from swift/xcode-autobuilder/xcode-autobuilder.cpp
rename to swift/swift-autobuilder/swift-autobuilder.cpp
index fd73d30b0ad..cbf7f217c75 100644
--- a/swift/xcode-autobuilder/xcode-autobuilder.cpp
+++ b/swift/swift-autobuilder/swift-autobuilder.cpp
@@ -1,11 +1,11 @@
#include
#include
#include
-#include "swift/xcode-autobuilder/XcodeTarget.h"
-#include "swift/xcode-autobuilder/XcodeBuildRunner.h"
-#include "swift/xcode-autobuilder/XcodeProjectParser.h"
+#include "swift/swift-autobuilder/XcodeTarget.h"
+#include "swift/swift-autobuilder/BuildRunner.h"
+#include "swift/swift-autobuilder/ProjectParser.h"
#include "swift/logging/SwiftLogging.h"
-#include "swift/xcode-autobuilder/CustomizingBuildLink.h"
+#include "swift/swift-autobuilder/CustomizingBuildLink.h"
static constexpr std::string_view uiTest = "com.apple.product-type.bundle.ui-testing";
static constexpr std::string_view unitTest = "com.apple.product-type.bundle.unit-test";
@@ -79,8 +79,9 @@ static bool autobuild(const CLIArgs& args) {
"contain no Swift source files, or are tests.");
return false;
} else if (!structure.xcodeEncountered && swiftPackages.empty()) {
- DIAGNOSE_ERROR(noProjectFound,
- "`autobuild` detected neither an Xcode project or workspace, nor a Swift package");
+ DIAGNOSE_ERROR(
+ noProjectFound,
+ "`autobuild` detected neither an Xcode project or workspace, nor a Swift package");
return false;
} else if (!xcodeTargets.empty()) {
LOG_INFO("Building Xcode target: {}", xcodeTargets.front());
diff --git a/swift/xcode-autobuilder/tests/.gitignore b/swift/swift-autobuilder/tests/.gitignore
similarity index 100%
rename from swift/xcode-autobuilder/tests/.gitignore
rename to swift/swift-autobuilder/tests/.gitignore
diff --git a/swift/xcode-autobuilder/tests/BUILD.bazel b/swift/swift-autobuilder/tests/BUILD.bazel
similarity index 83%
rename from swift/xcode-autobuilder/tests/BUILD.bazel
rename to swift/swift-autobuilder/tests/BUILD.bazel
index 3013dd47a10..f9a2b8eb178 100644
--- a/swift/xcode-autobuilder/tests/BUILD.bazel
+++ b/swift/swift-autobuilder/tests/BUILD.bazel
@@ -4,11 +4,11 @@
size = "small",
srcs = ["autobuild_tester.py"],
args = [
- "$(location //swift/xcode-autobuilder)",
+ "$(location //swift/swift-autobuilder)",
"$(location %s)" % test_dir,
],
data = [
- "//swift/xcode-autobuilder",
+ "//swift/swift-autobuilder",
test_dir,
] + glob([test_dir + "/**/*"]),
main = "autobuild_tester.py",
diff --git a/swift/xcode-autobuilder/tests/autobuild_tester.py b/swift/swift-autobuilder/tests/autobuild_tester.py
similarity index 100%
rename from swift/xcode-autobuilder/tests/autobuild_tester.py
rename to swift/swift-autobuilder/tests/autobuild_tester.py
diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/commands.expected b/swift/swift-autobuilder/tests/hello-autobuilder/commands.expected
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-autobuilder/commands.expected
rename to swift/swift-autobuilder/tests/hello-autobuilder/commands.expected
diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj
rename to swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj
diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj
rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj
diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected
rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected
diff --git a/swift/xcode-autobuilder/tests/hello-tests/commands.expected b/swift/swift-autobuilder/tests/hello-tests/commands.expected
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-tests/commands.expected
rename to swift/swift-autobuilder/tests/hello-tests/commands.expected
diff --git a/swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj
rename to swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj
diff --git a/swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/swift/xcode-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata
rename to swift/swift-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata
diff --git a/swift/xcode-autobuilder/tests/hello-workspace/commands.expected b/swift/swift-autobuilder/tests/hello-workspace/commands.expected
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-workspace/commands.expected
rename to swift/swift-autobuilder/tests/hello-workspace/commands.expected
diff --git a/swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj
rename to swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj
diff --git a/swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/swift/tools/autobuild.sh b/swift/tools/autobuild.sh
index bd7ded9e486..89bf3c12435 100755
--- a/swift/tools/autobuild.sh
+++ b/swift/tools/autobuild.sh
@@ -3,7 +3,7 @@
if [[ "$OSTYPE" == "darwin"* ]]; then
export CODEQL_SWIFT_CARTHAGE_EXEC=`which carthage`
export CODEQL_SWIFT_POD_EXEC=`which pod`
- exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/xcode-autobuilder"
+ exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/swift-autobuilder"
else
exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/autobuilder-incompatible-os"
fi