diff --git a/.github/workflows/swift-codegen.yml b/.github/workflows/swift-codegen.yml
index d5d74af87c2..46a27709717 100644
--- a/.github/workflows/swift-codegen.yml
+++ b/.github/workflows/swift-codegen.yml
@@ -15,18 +15,22 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2
+ - uses: actions/setup-python@v3
+ - uses: pre-commit/action@v3.0.0
+ name: Check that python code is properly formatted
+ with:
+ extra_args: autopep8 --all-files
- name: Run unit tests
run: |
bazel test //swift/codegen/test --test_output=errors
- - name: Check that QL generated code was checked in
- run: |
- bazel run //swift/codegen
- git add swift
- git diff --exit-code HEAD
+ - uses: pre-commit/action@v3.0.0
+ name: Check that QL generated code was checked in
+ with:
+ extra_args: swift-codegen --all-files
- name: Generate C++ files
run: |
- bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-headers
+ bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-cpp-files
- uses: actions/upload-artifact@v3
with:
- name: swift-generated-headers
- path: swift-generated-headers/*.h
+ name: swift-generated-cpp-files
+ path: swift-generated-cpp-files/**
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 1b44de000fb..d51681aa65c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -15,6 +15,12 @@ repos:
- id: clang-format
files: ^swift/.*\.(h|c|cpp)$
+ - repo: https://github.com/pre-commit/mirrors-autopep8
+ rev: v1.6.0
+ hooks:
+ - id: autopep8
+ files: ^swift/codegen/.*\.py
+
- repo: local
hooks:
- id: codeql-format
diff --git a/config/identical-files.json b/config/identical-files.json
index 53d3b74b3b0..81e07fe48cf 100644
--- a/config/identical-files.json
+++ b/config/identical-files.json
@@ -454,11 +454,11 @@
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp"
],
"IDE Contextual Queries": [
- "cpp/ql/src/IDEContextual.qll",
- "csharp/ql/src/IDEContextual.qll",
- "java/ql/src/IDEContextual.qll",
- "javascript/ql/src/IDEContextual.qll",
- "python/ql/src/analysis/IDEContextual.qll"
+ "cpp/ql/lib/IDEContextual.qll",
+ "csharp/ql/lib/IDEContextual.qll",
+ "java/ql/lib/IDEContextual.qll",
+ "javascript/ql/lib/IDEContextual.qll",
+ "python/ql/lib/analysis/IDEContextual.qll"
],
"SSA C#": [
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md
index 52dd2c7a843..c1cefbed8f9 100644
--- a/cpp/ql/lib/CHANGELOG.md
+++ b/cpp/ql/lib/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.3.0
+
+### Deprecated APIs
+
+* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
+
+### Bug Fixes
+
+* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
+
## 0.2.3
### New Features
diff --git a/cpp/ql/src/IDEContextual.qll b/cpp/ql/lib/IDEContextual.qll
similarity index 100%
rename from cpp/ql/src/IDEContextual.qll
rename to cpp/ql/lib/IDEContextual.qll
diff --git a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md b/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md
deleted file mode 100644
index 8a31f06ab98..00000000000
--- a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: feature
----
-* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
diff --git a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md b/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md
deleted file mode 100644
index fb301705e79..00000000000
--- a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: fix
----
-* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
diff --git a/cpp/ql/lib/change-notes/released/0.3.0.md b/cpp/ql/lib/change-notes/released/0.3.0.md
new file mode 100644
index 00000000000..8c45dc21817
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/0.3.0.md
@@ -0,0 +1,9 @@
+## 0.3.0
+
+### Deprecated APIs
+
+* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
+
+### Bug Fixes
+
+* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml
index 0b605901b42..95f6e3a0ba6 100644
--- a/cpp/ql/lib/codeql-pack.release.yml
+++ b/cpp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.2.3
+lastReleaseVersion: 0.3.0
diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/lib/definitions.qll
similarity index 100%
rename from cpp/ql/src/definitions.qll
rename to cpp/ql/lib/definitions.qll
diff --git a/cpp/ql/src/localDefinitions.ql b/cpp/ql/lib/localDefinitions.ql
similarity index 100%
rename from cpp/ql/src/localDefinitions.ql
rename to cpp/ql/lib/localDefinitions.ql
diff --git a/cpp/ql/src/localReferences.ql b/cpp/ql/lib/localReferences.ql
similarity index 100%
rename from cpp/ql/src/localReferences.ql
rename to cpp/ql/lib/localReferences.ql
diff --git a/cpp/ql/src/printAst.ql b/cpp/ql/lib/printAst.ql
similarity index 100%
rename from cpp/ql/src/printAst.ql
rename to cpp/ql/lib/printAst.ql
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index 28cddcb3b00..a20077271d7 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-all
-version: 0.3.0-dev
+version: 0.3.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md
index 449af46b6b8..2b404ff5288 100644
--- a/cpp/ql/src/CHANGELOG.md
+++ b/cpp/ql/src/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 0.2.0
+
## 0.1.4
## 0.1.3
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
index c72e25f61df..bd55008677c 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
@@ -18,7 +18,7 @@ import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.MustFlow
import PathGraph
-/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */
+/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */
predicate intentionallyReturnsStackPointer(Function f) {
f.getName().toLowerCase().matches(["%stack%", "%sp%"])
}
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql
index 27aeabbaf49..3f3997315d4 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql
@@ -133,7 +133,9 @@ TGlobalAddress globalAddress(Instruction instr) {
)
or
exists(FieldAddressInstruction fai | instr = fai |
- result = TFieldAddress(globalAddress(fai.getObjectAddress()), fai.getField())
+ result =
+ TFieldAddress(globalAddress(pragma[only_bind_into](fai.getObjectAddress())),
+ pragma[only_bind_out](fai.getField()))
)
or
result = globalAddress(instr.(PointerOffsetInstruction).getLeft())
diff --git a/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md
new file mode 100644
index 00000000000..cc5464d58b3
--- /dev/null
+++ b/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md
@@ -0,0 +1,4 @@
+---
+category: breaking
+---
+* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.
diff --git a/cpp/ql/src/change-notes/released/0.2.0.md b/cpp/ql/src/change-notes/released/0.2.0.md
new file mode 100644
index 00000000000..79a5f33514f
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/0.2.0.md
@@ -0,0 +1 @@
+## 0.2.0
diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml
index e8ee3af8ef9..5274e27ed52 100644
--- a/cpp/ql/src/codeql-pack.release.yml
+++ b/cpp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.4
+lastReleaseVersion: 0.2.0
diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml
index a373e4717d8..62cac967801 100644
--- a/cpp/ql/src/qlpack.yml
+++ b/cpp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-queries
-version: 0.2.0-dev
+version: 0.2.1-dev
groups:
- cpp
- queries
diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
index 0bb47844d19..30c583ee913 100644
--- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
+++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 1.2.0
+
## 1.1.4
## 1.1.3
diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md
new file mode 100644
index 00000000000..0ff42339575
--- /dev/null
+++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md
@@ -0,0 +1 @@
+## 1.2.0
diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml
index 26cbcd3f123..75430e73d1c 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.1.4
+lastReleaseVersion: 1.2.0
diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
index 9cb7bec181f..bc7eaf4142c 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.2.0-dev
+version: 1.2.1-dev
groups:
- csharp
- solorigate
diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
index 0bb47844d19..30c583ee913 100644
--- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
+++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 1.2.0
+
## 1.1.4
## 1.1.3
diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md
new file mode 100644
index 00000000000..0ff42339575
--- /dev/null
+++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md
@@ -0,0 +1 @@
+## 1.2.0
diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml
index 26cbcd3f123..75430e73d1c 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.1.4
+lastReleaseVersion: 1.2.0
diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml
index 07419f1b469..00725e23666 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.2.0-dev
+version: 1.2.1-dev
groups:
- csharp
- solorigate
diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md
index 3df8b95eeb6..3f49fe5ade3 100644
--- a/csharp/ql/lib/CHANGELOG.md
+++ b/csharp/ql/lib/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.3.0
+
+### Deprecated APIs
+
+* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
+
## 0.2.3
## 0.2.2
diff --git a/csharp/ql/src/IDEContextual.qll b/csharp/ql/lib/IDEContextual.qll
similarity index 100%
rename from csharp/ql/src/IDEContextual.qll
rename to csharp/ql/lib/IDEContextual.qll
diff --git a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/csharp/ql/lib/change-notes/released/0.3.0.md
similarity index 83%
rename from go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md
rename to csharp/ql/lib/change-notes/released/0.3.0.md
index 2bd95798f89..54af6e00ac0 100644
--- a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md
+++ b/csharp/ql/lib/change-notes/released/0.3.0.md
@@ -1,4 +1,5 @@
----
-category: deprecated
----
+## 0.3.0
+
+### Deprecated APIs
+
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml
index 0b605901b42..95f6e3a0ba6 100644
--- a/csharp/ql/lib/codeql-pack.release.yml
+++ b/csharp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.2.3
+lastReleaseVersion: 0.3.0
diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/lib/definitions.qll
similarity index 100%
rename from csharp/ql/src/definitions.qll
rename to csharp/ql/lib/definitions.qll
diff --git a/csharp/ql/src/localDefinitions.ql b/csharp/ql/lib/localDefinitions.ql
similarity index 100%
rename from csharp/ql/src/localDefinitions.ql
rename to csharp/ql/lib/localDefinitions.ql
diff --git a/csharp/ql/src/localReferences.ql b/csharp/ql/lib/localReferences.ql
similarity index 100%
rename from csharp/ql/src/localReferences.ql
rename to csharp/ql/lib/localReferences.ql
diff --git a/csharp/ql/src/printAst.ql b/csharp/ql/lib/printAst.ql
similarity index 100%
rename from csharp/ql/src/printAst.ql
rename to csharp/ql/lib/printAst.ql
diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml
index 2e2d17e36fa..3f371c01e92 100644
--- a/csharp/ql/lib/qlpack.yml
+++ b/csharp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-all
-version: 0.3.0-dev
+version: 0.3.1-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll
index 7b9e78d2c4b..a076f7a2e45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- simpleLocalFlowStepExt(n1, n2) and
+ simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config)
)
or
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config)
)
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- jumpStepCached(n1, n2) and
+ jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
)
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, n2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
exists(Node n1, Node n2 |
node1.asNode() = n1 and
node2.asNode() = n2 and
- config.isAdditionalFlowStep(n1, s1, n2, s2) and
+ config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
stepFilter(node1, node2, config) and
not stateBarrier(node1, s1, config) and
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
pragma[nomagic]
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
- readSet(node1.asNode(), c, node2.asNode()) and
+ readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
stepFilter(node1, node2, config)
or
exists(Node n |
@@ -562,7 +562,8 @@ pragma[nomagic]
private predicate store(
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
) {
- store(node1.asNode(), tc, node2.asNode(), contentType) and
+ store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
+ contentType) and
read(_, tc.getContent(), _, config) and
stepFilter(node1, node2, config)
}
diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md
index bc553b74fe4..e7ce0b0b471 100644
--- a/csharp/ql/src/CHANGELOG.md
+++ b/csharp/ql/src/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.2.0
+
+### Query Metadata Changes
+
+* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
+
+### Minor Analysis Improvements
+
+* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
+* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
+
## 0.1.4
## 0.1.3
diff --git a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md b/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md
deleted file mode 100644
index b80e90e0434..00000000000
--- a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
\ No newline at end of file
diff --git a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md b/csharp/ql/src/change-notes/2022-06-14-madformatchange.md
deleted file mode 100644
index 1dd215a89c7..00000000000
--- a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
\ No newline at end of file
diff --git a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md b/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md
deleted file mode 100644
index d5cfc4d35e1..00000000000
--- a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: queryMetadata
----
-* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
diff --git a/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md
new file mode 100644
index 00000000000..a27c68766c0
--- /dev/null
+++ b/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md
@@ -0,0 +1,4 @@
+---
+category: breaking
+---
+* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.
diff --git a/csharp/ql/src/change-notes/released/0.2.0.md b/csharp/ql/src/change-notes/released/0.2.0.md
new file mode 100644
index 00000000000..1b7d3928c1c
--- /dev/null
+++ b/csharp/ql/src/change-notes/released/0.2.0.md
@@ -0,0 +1,10 @@
+## 0.2.0
+
+### Query Metadata Changes
+
+* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
+
+### Minor Analysis Improvements
+
+* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
+* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml
index e8ee3af8ef9..5274e27ed52 100644
--- a/csharp/ql/src/codeql-pack.release.yml
+++ b/csharp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.4
+lastReleaseVersion: 0.2.0
diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml
index a9d6dcf0e69..1002c6a56ad 100644
--- a/csharp/ql/src/qlpack.yml
+++ b/csharp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-queries
-version: 0.2.0-dev
+version: 0.2.1-dev
groups:
- csharp
- queries
diff --git a/docs/codeql/reusables/beta-note-package-management.rst b/docs/codeql/reusables/beta-note-package-management.rst
index a4fd362a70c..7697c9a47d9 100644
--- a/docs/codeql/reusables/beta-note-package-management.rst
+++ b/docs/codeql/reusables/beta-note-package-management.rst
@@ -2,4 +2,4 @@
Note
- The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install version 2.6.0 or higher of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases.
\ No newline at end of file
+ The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install the latest version of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases.
diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md
index 1767b297fc6..112f4fab585 100644
--- a/go/ql/lib/CHANGELOG.md
+++ b/go/ql/lib/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.2.0
+
+### Deprecated APIs
+
+* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
+
## 0.1.4
## 0.1.3
diff --git a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/go/ql/lib/change-notes/released/0.2.0.md
similarity index 83%
rename from cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md
rename to go/ql/lib/change-notes/released/0.2.0.md
index 2bd95798f89..ded60d11b7e 100644
--- a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md
+++ b/go/ql/lib/change-notes/released/0.2.0.md
@@ -1,4 +1,5 @@
----
-category: deprecated
----
+## 0.2.0
+
+### Deprecated APIs
+
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml
index e8ee3af8ef9..5274e27ed52 100644
--- a/go/ql/lib/codeql-pack.release.yml
+++ b/go/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.4
+lastReleaseVersion: 0.2.0
diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml
index f416a2612a8..964f5d4dd13 100644
--- a/go/ql/lib/qlpack.yml
+++ b/go/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/go-all
-version: 0.2.0-dev
+version: 0.2.1-dev
groups: go
dbscheme: go.dbscheme
extractor: go
diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md
index 541c8c95377..bed2509f5d3 100644
--- a/go/ql/src/CHANGELOG.md
+++ b/go/ql/src/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 0.2.0
+
## 0.1.4
## 0.1.3
diff --git a/go/ql/src/change-notes/released/0.2.0.md b/go/ql/src/change-notes/released/0.2.0.md
new file mode 100644
index 00000000000..79a5f33514f
--- /dev/null
+++ b/go/ql/src/change-notes/released/0.2.0.md
@@ -0,0 +1 @@
+## 0.2.0
diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml
index e8ee3af8ef9..5274e27ed52 100644
--- a/go/ql/src/codeql-pack.release.yml
+++ b/go/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.1.4
+lastReleaseVersion: 0.2.0
diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml
index 062631cb68b..80a4430b8da 100644
--- a/go/ql/src/qlpack.yml
+++ b/go/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/go-queries
-version: 0.2.0-dev
+version: 0.2.1-dev
groups:
- go
- queries
diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv
index b9d52d9d75e..06ec8d978d4 100644
--- a/java/documentation/library-coverage/coverage.csv
+++ b/java/documentation/library-coverage/coverage.csv
@@ -1,121 +1,121 @@
-package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value
-android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,18,85
-android.content,24,27,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,27,,31,77
-android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,30,
-android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15
-android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,81
-android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,,
-android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,2,,
-android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1,
-androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61
-cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
-com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,62,23
-com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17
-com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551
-com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,
-com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1
-com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,
-com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7,
-com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,
-com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,
-flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
-groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
-jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,,
-jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
-jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
-jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
-jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55
-java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,39,
-java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,46,12
-java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,3,7,
-java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,6,
-java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,
-java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,24,414
-javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,,
-javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
-javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
-javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,
-javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,
-javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,
-javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,
-javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2,
-javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,
-javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
-javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
-javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55
-javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,6,
-javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,
-jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10
-kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,
-ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,
-okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,22,25
-org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
-org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
-org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
-org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,547,14
-org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131
-org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,
-org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,
-org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52
-org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,
-org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,39,
-org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
-org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
-org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,3,62,8
-org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,57,
-org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,
-org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4
-org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
-org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,
-org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,
-org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,
-org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,
-org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38
-org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,
-org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,
-org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4
-org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30
-org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
-org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
-org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,60,10
-org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,
-org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,
-org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,
-org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
-org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,
-org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,
-org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32
-org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52
-org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
-org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,3,,
-org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
-org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13,
-org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,
-org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25
-org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
-org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,
-play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,
-ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
-ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
-ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
-ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48
-ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
-ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
-ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
-ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
-ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
-retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
+package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value
+android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,,18,85
+android.content,24,31,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,4,,27,,31,77
+android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,30,
+android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15
+android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81
+android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,16,,
+android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,,
+android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1,
+androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,5,,27,61
+cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
+com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,62,23
+com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17
+com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551
+com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,
+com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1
+com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,
+com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7,
+com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,
+com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
+groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
+jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
+jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
+jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
+jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
+java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,39,
+java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7,
+java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6,
+java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
+java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,414
+javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
+javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
+javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
+javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,
+javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,
+javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,
+javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,
+javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2,
+javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,
+javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
+javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
+javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
+javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6,
+javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,
+jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10
+kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
+net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,,
+ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,
+okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,22,25
+org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
+org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
+org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
+org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,547,14
+org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131
+org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,
+org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,
+org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52
+org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
+org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39,
+org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
+org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
+org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,,3,62,8
+org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,57,
+org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,
+org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,4,4
+org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,,
+org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
+org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,
+org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,
+org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38
+org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,
+org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,
+org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,2,4
+org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30
+org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
+org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
+org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,60,10
+org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,
+org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,
+org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,
+org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,
+org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,
+org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32
+org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52
+org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
+org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,3,,
+org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
+org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13,
+org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,
+org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25
+org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
+org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,
+play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,
+ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
+ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
+ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
+ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48
+ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
+ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
+ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
+ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
+ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
+retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst
index cd8995b77d5..7b45a3115b1 100644
--- a/java/documentation/library-coverage/coverage.rst
+++ b/java/documentation/library-coverage/coverage.rst
@@ -7,7 +7,7 @@ Java framework & library support
:widths: auto
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission`
- Android,``android.*``,46,424,108,,,3,67,,,
+ Android,``android.*``,52,424,108,,,3,67,,,
`Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,,
`Apache Commons IO `_,``org.apache.commons.io``,,561,104,89,,,,,,15
`Apache Commons Lang `_,``org.apache.commons.lang3``,,424,,,,,,,,
@@ -19,5 +19,5 @@ Java framework & library support
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
`Spring `_,``org.springframework.*``,29,476,101,,,,19,14,,29
Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3
- Totals,,211,6410,1474,117,6,10,107,33,1,84
+ Totals,,217,6410,1474,117,6,10,107,33,1,84
diff --git a/java/kotlin-extractor/build.gradle b/java/kotlin-extractor/build.gradle
index a4bf5748c29..3926962fd3d 100644
--- a/java/kotlin-extractor/build.gradle
+++ b/java/kotlin-extractor/build.gradle
@@ -35,8 +35,8 @@ sourceSets {
"utils/versions/v_1_5_21/*.kt",
"utils/versions/v_1_5_31/*.kt",
"utils/versions/v_1_6_10/*.kt",
- "utils/versions/v_1_7_0-RC/*.kt",
- // "utils/versions/v_1_6_20/*.kt",
+ "utils/versions/v_1_6_20/*.kt",
+ // "utils/versions/v_1_7_0/*.kt",
]
}
}
diff --git a/java/kotlin-extractor/gradle.properties b/java/kotlin-extractor/gradle.properties
index 69e0a36ba4c..16f621c2d74 100644
--- a/java/kotlin-extractor/gradle.properties
+++ b/java/kotlin-extractor/gradle.properties
@@ -1,5 +1,5 @@
kotlin.code.style=official
-kotlinVersion=1.6.20
+kotlinVersion=1.7.0
GROUP=com.github.codeql
VERSION_NAME=0.0.1
diff --git a/java/kotlin-extractor/kotlin_plugin_versions.py b/java/kotlin-extractor/kotlin_plugin_versions.py
index bd60c019236..e84764dbefc 100755
--- a/java/kotlin-extractor/kotlin_plugin_versions.py
+++ b/java/kotlin-extractor/kotlin_plugin_versions.py
@@ -21,7 +21,7 @@ def version_string_to_tuple(version):
m = re.match(r'([0-9]+)\.([0-9]+)\.([0-9]+)(.*)', version)
return tuple([int(m.group(i)) for i in range(1, 4)] + [m.group(4)])
-many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.21', '1.5.31', '1.6.10', '1.7.0-RC', '1.6.20' ]
+many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.21', '1.5.31', '1.6.10', '1.6.20', '1.7.0' ]
many_versions_tuples = [version_string_to_tuple(v) for v in many_versions]
diff --git a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt
index 5edb16271c1..b1b2823b6b5 100644
--- a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt
@@ -6,9 +6,11 @@ import com.semmle.extractor.java.OdasaOutput
import com.semmle.util.data.StringDigestor
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isFileClass
import org.jetbrains.kotlin.ir.util.packageFqName
import org.jetbrains.kotlin.ir.util.parentClassOrNull
+import org.jetbrains.kotlin.name.FqName
import java.io.File
import java.util.ArrayList
import java.util.HashSet
@@ -16,18 +18,20 @@ import java.util.zip.GZIPOutputStream
class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: TrapWriter) {
- val externalDeclsDone = HashSet()
+ val declBinaryNames = HashMap()
+ val externalDeclsDone = HashSet>()
val externalDeclWorkList = ArrayList>()
val propertySignature = ";property"
val fieldSignature = ";field"
- fun extractLater(d: IrDeclaration, signature: String): Boolean {
+ fun extractLater(d: IrDeclarationWithName, signature: String): Boolean {
if (d !is IrClass && !isExternalFileClassMember(d)) {
logger.errorElement("External declaration is neither a class, nor a top-level declaration", d)
return false
}
- val ret = externalDeclsDone.add(d)
+ val declBinaryName = declBinaryNames.getOrPut(d) { getIrDeclBinaryName(d) }
+ val ret = externalDeclsDone.add(Pair(declBinaryName, signature))
if (ret) externalDeclWorkList.add(Pair(d, signature))
return ret
}
diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
index 743c04bd33f..21b35fbcdd1 100644
--- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
@@ -6,6 +6,7 @@ import com.github.codeql.utils.versions.functionN
import com.github.codeql.utils.versions.getIrStubFromDescriptor
import com.semmle.extractor.java.OdasaOutput
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
import org.jetbrains.kotlin.descriptors.*
@@ -41,7 +42,7 @@ open class KotlinFileExtractor(
globalExtensionState: KotlinExtractorGlobalState
): KotlinUsesExtractor(logger, tw, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, globalExtensionState) {
- inline fun with(kind: String, element: IrElement, f: () -> T): T {
+ private inline fun with(kind: String, element: IrElement, f: () -> T): T {
val name = when (element) {
is IrFile -> element.name
is IrDeclarationWithName -> element.name.asString()
@@ -80,12 +81,13 @@ open class KotlinFileExtractor(
}
}
- file.declarations.map { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
+ file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
extractStaticInitializer(file, null)
CommentExtractor(this, file, tw.fileId).extract()
}
}
+ @OptIn(ObsoleteDescriptorBasedAPI::class)
private fun isFake(d: IrDeclarationWithVisibility): Boolean {
val visibility = d.visibility
if (visibility is DelegatedDescriptorVisibility && visibility.delegate == Visibilities.InvisibleFake) {
@@ -94,6 +96,9 @@ open class KotlinFileExtractor(
if (d.isFakeOverride) {
return true
}
+ if ((d as? IrFunction)?.descriptor?.isHiddenToOvercomeSignatureClash == true) {
+ return true
+ }
return false
}
@@ -177,7 +182,7 @@ open class KotlinFileExtractor(
}
}
- fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? {
+ private fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? {
with("type parameter", tp) {
val parentId = getTypeParameterParentLabel(tp) ?: return null
val id = tw.getLabelFor(getTypeParameterLabel(tp))
@@ -212,7 +217,7 @@ open class KotlinFileExtractor(
}
}
- fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) {
+ private fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) {
with("visibility", elementForLocation) {
when (v) {
DescriptorVisibilities.PRIVATE -> addModifiers(id, "private")
@@ -246,7 +251,7 @@ open class KotlinFileExtractor(
}
}
- fun extractClassModifiers(c: IrClass, id: Label) {
+ private fun extractClassModifiers(c: IrClass, id: Label) {
with("class modifiers", c) {
when (c.modality) {
Modality.FINAL -> addModifiers(id, "final")
@@ -310,8 +315,21 @@ open class KotlinFileExtractor(
val locId = getLocation(c, argsIncludingOuterClasses)
tw.writeHasLocation(id, locId)
- // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters.
- extractEnclosingClass(c, id, locId, argsIncludingOuterClasses?.drop(c.typeParameters.size) ?: listOf())
+ // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class.
+ // For example, in `class Outer { inner class Inner { } }`, `Inner` nests within `Outer` and raw `Inner<>` within `Outer<>`,
+ // but for a similar non-`inner` (in Java terms, static nested) class both `Inner` and `Inner<>` nest within the unbound type `Outer`.
+ val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.map { // Would use `firstNotNullOfOrNull`, but this doesn't exist in Kotlin 1.4
+ when(it) {
+ is IrClass -> when {
+ it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type.
+ !(it.isInner || it.isLocal) -> false // No type parameters seen yet, and this is a static class -- extract an enclosing unbound type.
+ else -> null // No type parameters seen here, but may be visible enclosing type parameters; keep searching.
+ }
+ else -> null // Look through enclosing non-class entities (this may need to change)
+ }
+ }.firstOrNull { it != null } ?: false)
+
+ extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf())
return id
}
@@ -367,6 +385,29 @@ open class KotlinFileExtractor(
tw.writeHasLocation(stmtId, locId)
}
+ private fun extractObinitFunction(c: IrClass, parentId: Label) {
+ // add method:
+ val obinitLabel = getObinitLabel(c)
+ val obinitId = tw.getLabelFor(obinitLabel)
+ val returnType = useType(pluginContext.irBuiltIns.unitType, TypeContext.RETURN)
+ tw.writeMethods(obinitId, "", "()", returnType.javaResult.id, parentId, obinitId)
+ tw.writeMethodsKotlinType(obinitId, returnType.kotlinResult.id)
+
+ val locId = tw.getLocation(c)
+ tw.writeHasLocation(obinitId, locId)
+
+ addModifiers(obinitId, "private")
+
+ // add body:
+ val blockId = tw.getFreshIdLabel()
+ tw.writeStmts_block(blockId, obinitId, 0, obinitId)
+ tw.writeHasLocation(blockId, locId)
+
+ extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) }
+ }
+
+ val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic")
+
fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label {
with("class source", c) {
DeclarationStackAdjuster(c).use {
@@ -403,9 +444,10 @@ open class KotlinFileExtractor(
c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) }
if (extractDeclarations) {
- c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
+ c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
if (extractStaticInitializer)
extractStaticInitializer(c, id)
+ extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies)
}
if (c.isNonCompanionObject) {
// For `object MyObject { ... }`, the .class has an
@@ -421,6 +463,9 @@ open class KotlinFileExtractor(
addModifiers(instance.id, "public", "static", "final")
tw.writeClass_object(id.cast(), instance.id)
}
+ if (extractFunctionBodies && needsObinitFunction(c)) {
+ extractObinitFunction(c, id)
+ }
extractClassModifiers(c, id)
extractClassSupertypes(c, id, inReceiverContext = true) // inReceiverContext = true is specified to force extraction of member prototypes of base types
@@ -430,7 +475,78 @@ open class KotlinFileExtractor(
}
}
- private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List) {
+ private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
+
+ // Add synthetic forwarders for any JvmStatic methods or properties:
+ val companionObject = c.companionObject() ?: return
+
+ val cType = c.typeWith()
+ val companionType = companionObject.typeWith()
+
+ fun makeProxyFunction(f: IrFunction) {
+ // Emit a function in class `c` that delegates to the same function defined on `c.CompanionInstance`.
+ val proxyFunctionId = tw.getLabelFor(getFunctionLabel(f, classId, listOf()))
+ // We extract the function prototype with its ID overridden to belong to `c` not the companion object,
+ // but suppress outputting the body, which we will replace with a delegating call below.
+ forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null, extractOrigin = false)
+ addModifiers(proxyFunctionId, "static")
+ tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind)
+ if (extractFunctionBodies) {
+ val realFunctionLocId = tw.getLocation(f)
+ extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId ->
+ extractRawMethodAccess(
+ f,
+ realFunctionLocId,
+ f.returnType,
+ proxyFunctionId,
+ returnId,
+ 0,
+ returnId,
+ f.valueParameters.size,
+ { argParent, idxOffset ->
+ f.valueParameters.forEachIndexed { idx, param ->
+ val syntheticParamId = useValueParameter(param, proxyFunctionId)
+ extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParent, idxOffset + idx, proxyFunctionId, returnId)
+ }
+ },
+ companionType,
+ { callId ->
+ val companionField = useCompanionObjectClassInstance(companionObject)?.id
+ extractVariableAccess(companionField, companionType, realFunctionLocId, callId, -1, proxyFunctionId, returnId).also { varAccessId ->
+ extractTypeAccessRecursive(cType, realFunctionLocId, varAccessId, -1, proxyFunctionId, returnId)
+ }
+ },
+ null
+ )
+ }
+ }
+ }
+
+ companionObject.declarations.forEach {
+ if (shouldExtractDecl(it, extractPrivateMembers)) {
+ val wholeDeclAnnotated = it.hasAnnotation(jvmStaticFqName)
+ when(it) {
+ is IrFunction -> {
+ if (wholeDeclAnnotated)
+ makeProxyFunction(it)
+ }
+ is IrProperty -> {
+ it.getter?.let { getter ->
+ if (wholeDeclAnnotated || getter.hasAnnotation(jvmStaticFqName))
+ makeProxyFunction(getter)
+ }
+ it.setter?.let { setter ->
+ if (wholeDeclAnnotated || setter.hasAnnotation(jvmStaticFqName))
+ makeProxyFunction(setter)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If `parentClassTypeArguments` is null, the parent class is a raw type.
+ private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List?) {
with("enclosing class", innerDeclaration) {
var parent: IrDeclarationParent? = innerDeclaration.parent
while (parent != null) {
@@ -478,7 +594,7 @@ open class KotlinFileExtractor(
data class FieldResult(val id: Label, val name: String)
- fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
+ private fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
val parent = c.parent
if(!c.isCompanion) {
logger.error("Using companion instance for non-companion class")
@@ -496,7 +612,7 @@ open class KotlinFileExtractor(
}
}
- fun useObjectClassInstance(c: IrClass): FieldResult {
+ private fun useObjectClassInstance(c: IrClass): FieldResult {
if(!c.isNonCompanionObject) {
logger.error("Using instance for non-object class")
}
@@ -567,6 +683,8 @@ open class KotlinFileExtractor(
tw.writeMethods(clinitId, "", "()", returnType.javaResult.id, parentId, clinitId)
tw.writeMethodsKotlinType(clinitId, returnType.kotlinResult.id)
+ tw.writeCompiler_generated(clinitId, CompilerGeneratedKinds.CLASS_INITIALISATION_METHOD.kind)
+
val locId = tw.getWholeFileLocation()
tw.writeHasLocation(clinitId, locId)
@@ -689,13 +807,13 @@ open class KotlinFileExtractor(
}
}
- fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) =
+ private fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) =
if (isFake(f))
null
else
forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null)
- fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?): Label {
+ private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?, extractOrigin: Boolean = true): Label {
with("function", f) {
DeclarationStackAdjuster(f).use {
@@ -704,12 +822,9 @@ open class KotlinFileExtractor(
val id =
idOverride
- ?: if (f.isLocalFunction())
- getLocallyVisibleFunctionLabels(f).function
- else
- // If this is a class that would ordinarily be replaced by a Java equivalent (e.g. kotlin.Map -> java.util.Map),
- // don't replace here, really extract the Kotlin version:
- useFunction(f, parentId, classTypeArgsIncludingOuterClasses, noReplace = true)
+ ?: // If this is a class that would ordinarily be replaced by a Java equivalent (e.g. kotlin.Map -> java.util.Map),
+ // don't replace here, really extract the Kotlin version:
+ useFunction(f, parentId, classTypeArgsIncludingOuterClasses, noReplace = true)
val sourceDeclaration =
if (typeSubstitution != null && idOverride == null)
@@ -755,6 +870,16 @@ open class KotlinFileExtractor(
val methodId = id.cast()
tw.writeMethods(methodId, shortName.nameInDB, "${shortName.nameInDB}$paramsSignature", returnType.javaResult.id, parentId, sourceDeclaration.cast())
tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id)
+ if (extractOrigin) {
+ when (f.origin) {
+ IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
+ tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind)
+ IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR ->
+ tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind)
+ IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER ->
+ tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind)
+ }
+ }
if (extractMethodAndParameterTypeAccesses) {
extractTypeAccessRecursive(substReturnType, locId, id, -1)
@@ -774,10 +899,13 @@ open class KotlinFileExtractor(
}
extractVisibility(f, id, f.visibility)
- if (isStaticFunction(f)) {
+
+ if (f.isInline) {
+ addModifiers(id, "inline")
+ }
+ if (f.shouldExtractAsStatic) {
addModifiers(id, "static")
}
-
if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) {
addModifiers(id, "override")
}
@@ -793,7 +921,7 @@ open class KotlinFileExtractor(
&& f.symbol !is IrConstructorSymbol // not a constructor
}
- fun extractField(f: IrField, parentId: Label): Label {
+ private fun extractField(f: IrField, parentId: Label): Label {
with("field", f) {
DeclarationStackAdjuster(f).use {
declarationStack.push(f)
@@ -827,7 +955,7 @@ open class KotlinFileExtractor(
return id
}
- fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) {
+ private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) {
with("property", p) {
if (isFake(p)) return
@@ -846,6 +974,9 @@ open class KotlinFileExtractor(
val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast()
if (getterId != null) {
tw.writeKtPropertyGetters(id, getterId)
+ if (getter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) {
+ tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind)
+ }
}
} else {
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
@@ -860,6 +991,9 @@ open class KotlinFileExtractor(
val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast()
if (setterId != null) {
tw.writeKtPropertySetters(id, setterId)
+ if (setter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) {
+ tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind)
+ }
}
} else {
if (p.isVar && !isExternalDeclaration(p)) {
@@ -896,7 +1030,7 @@ open class KotlinFileExtractor(
}
}
- fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) {
+ private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) {
with("enum entry", ee) {
DeclarationStackAdjuster(ee).use {
val id = useEnumEntry(ee)
@@ -918,7 +1052,7 @@ open class KotlinFileExtractor(
}
}
- fun extractTypeAlias(ta: IrTypeAlias) {
+ private fun extractTypeAlias(ta: IrTypeAlias) {
with("type alias", ta) {
if (ta.typeParameters.isNotEmpty()) {
// TODO: Extract this information
@@ -933,7 +1067,7 @@ open class KotlinFileExtractor(
}
}
- fun extractBody(b: IrBody, callable: Label) {
+ private fun extractBody(b: IrBody, callable: Label) {
with("body", b) {
when (b) {
is IrBlockBody -> extractBlockBody(b, callable)
@@ -946,7 +1080,7 @@ open class KotlinFileExtractor(
}
}
- fun extractBlockBody(b: IrBlockBody, callable: Label) {
+ private fun extractBlockBody(b: IrBlockBody, callable: Label) {
with("block body", b) {
val id = tw.getFreshIdLabel()
val locId = tw.getLocation(b)
@@ -958,7 +1092,7 @@ open class KotlinFileExtractor(
}
}
- fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) {
+ private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) {
with("synthetic body", b) {
when (b.kind) {
IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
@@ -967,17 +1101,23 @@ open class KotlinFileExtractor(
}
}
- fun extractExpressionBody(b: IrExpressionBody, callable: Label) {
+ private fun extractExpressionBody(b: IrExpressionBody, callable: Label) {
with("expression body", b) {
- val blockId = tw.getFreshIdLabel()
val locId = tw.getLocation(b)
- tw.writeStmts_block(blockId, callable, 0, callable)
- tw.writeHasLocation(blockId, locId)
+ extractExpressionBody(callable, locId).also { returnId ->
+ extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
+ }
+ }
+ }
- val returnId = tw.getFreshIdLabel()
+ fun extractExpressionBody(callable: Label, locId: Label): Label {
+ val blockId = tw.getFreshIdLabel()
+ tw.writeStmts_block(blockId, callable, 0, callable)
+ tw.writeHasLocation(blockId, locId)
+
+ return tw.getFreshIdLabel().also { returnId ->
tw.writeStmts_returnstmt(returnId, blockId, 0, callable)
tw.writeHasLocation(returnId, locId)
- extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
}
}
@@ -991,7 +1131,7 @@ open class KotlinFileExtractor(
return v
}
- fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) {
+ private fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) {
with("variable", v) {
val stmtId = tw.getFreshIdLabel()
val locId = tw.getLocation(getVariableLocationProvider(v))
@@ -1001,7 +1141,7 @@ open class KotlinFileExtractor(
}
}
- fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
+ private fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
with("variable expr", v) {
val varId = useVariable(v)
val exprId = tw.getFreshIdLabel()
@@ -1025,7 +1165,7 @@ open class KotlinFileExtractor(
}
}
- fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) {
+ private fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) {
with("statement", s) {
when(s) {
is IrExpression -> {
@@ -1045,7 +1185,7 @@ open class KotlinFileExtractor(
tw.writeKtLocalFunction(ids.function)
if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) {
- tw.writeCompiler_generated(classId, 1)
+ tw.writeCompiler_generated(classId, CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS.kind)
}
} else {
logger.errorElement("Expected to find local function", s)
@@ -1248,10 +1388,48 @@ open class KotlinFileExtractor(
typeArguments: List = listOf(),
extractClassTypeArguments: Boolean = false) {
+ val locId = tw.getLocation(callsite)
+
+ extractRawMethodAccess(
+ syntacticCallTarget,
+ locId,
+ callsite.type,
+ enclosingCallable,
+ callsiteParent,
+ childIdx,
+ enclosingStmt,
+ valueArguments.size,
+ { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
+ dispatchReceiver?.type,
+ dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
+ extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
+ typeArguments,
+ extractClassTypeArguments
+ )
+
+ }
+
+
+ fun extractRawMethodAccess(
+ syntacticCallTarget: IrFunction,
+ locId: Label,
+ returnType: IrType,
+ enclosingCallable: Label,
+ callsiteParent: Label,
+ childIdx: Int,
+ enclosingStmt: Label,
+ nValueArguments: Int,
+ extractValueArguments: (Label, Int) -> Unit,
+ drType: IrType?,
+ extractDispatchReceiver: ((Label) -> Unit)?,
+ extractExtensionReceiver: ((Label) -> Unit)?,
+ typeArguments: List = listOf(),
+ extractClassTypeArguments: Boolean = false) {
+
val callTarget = syntacticCallTarget.target.realOverrideTarget
val id = tw.getFreshIdLabel()
- val type = useType(callsite.type)
- val locId = tw.getLocation(callsite)
+ val type = useType(returnType)
+
tw.writeExprs_methodaccess(id, type.javaResult.id, callsiteParent, childIdx)
tw.writeExprsKotlinType(id, type.kotlinResult.id)
tw.writeHasLocation(id, locId)
@@ -1261,8 +1439,6 @@ open class KotlinFileExtractor(
// type arguments at index -2, -3, ...
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
- val drType = dispatchReceiver?.type
-
val isFunctionInvoke = drType != null
&& drType is IrSimpleType
&& drType.isFunctionOrKFunction()
@@ -1305,44 +1481,48 @@ open class KotlinFileExtractor(
tw.writeCallableBinding(id, methodId)
- if (dispatchReceiver != null) {
- extractExpressionExpr(dispatchReceiver, enclosingCallable, id, -1, enclosingStmt)
- } else if (isStaticFunction(callTarget)) {
+ if (callTarget.shouldExtractAsStatic) {
extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt)
+ } else if (extractDispatchReceiver != null) {
+ extractDispatchReceiver(id)
}
}
- val idxOffset = if (extensionReceiver != null) 1 else 0
+ val idxOffset = if (extractExtensionReceiver != null) 1 else 0
val argParent = if (isBigArityFunctionInvoke) {
- extractArrayCreationWithInitializer(id, valueArguments.size + idxOffset, locId, enclosingCallable, enclosingStmt)
+ extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt)
} else {
id
}
- if (extensionReceiver != null) {
- extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt)
+ if (extractExtensionReceiver != null) {
+ extractExtensionReceiver(argParent)
}
- extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset)
+ extractValueArguments(argParent, idxOffset)
}
private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) {
- if (target.isStaticOfClass) {
+ if (target.shouldExtractAsStaticMemberOfClass) {
extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
- } else if (target.isStaticOfFile) {
+ } else if (target.shouldExtractAsStaticMemberOfFile) {
extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
}
}
- private val IrDeclaration.isStaticOfClass: Boolean
- get() = this.isStatic && parent is IrClass
+ private val IrDeclaration.shouldExtractAsStaticMemberOfClass: Boolean
+ get() = this.shouldExtractAsStatic && parent is IrClass
- private val IrDeclaration.isStaticOfFile: Boolean
- get() = this.isStatic && parent is IrFile
+ private val IrDeclaration.shouldExtractAsStaticMemberOfFile: Boolean
+ get() = this.shouldExtractAsStatic && parent is IrFile
- private val IrDeclaration.isStatic: Boolean
- get() = this is IrSimpleFunction && dispatchReceiverParameter == null ||
+ private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) =
+ f.parentClassOrNull?.isNonCompanionObject == true &&
+ (f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true)
+
+ private val IrDeclaration.shouldExtractAsStatic: Boolean
+ get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) ||
this is IrField && this.isStatic ||
this is IrEnumEntry
@@ -1364,7 +1544,7 @@ open class KotlinFileExtractor(
}
}
- fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
+ private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
val jvmIntrinsicsClass by lazy {
val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner
@@ -1372,7 +1552,7 @@ open class KotlinFileExtractor(
result
}
- fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
+ private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
val result = jvmIntrinsicsClass?.let { findFunction(it, name) }
if(result == null) {
logger.errorElement("Couldn't find JVM intrinsic function $name", warnAgainstElement)
@@ -1466,7 +1646,7 @@ open class KotlinFileExtractor(
result
}
- fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
+ private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting match for $pkgName $classNameLogged $fName")
@@ -1510,10 +1690,10 @@ open class KotlinFileExtractor(
return true
}
- fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
+ private fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
isFunction(target, pkgName, className, { it == className }, fName, hasQuestionMark)
- fun isNumericFunction(target: IrFunction, fName: String): Boolean {
+ private fun isNumericFunction(target: IrFunction, fName: String): Boolean {
return isFunction(target, "kotlin", "Int", fName) ||
isFunction(target, "kotlin", "Byte", fName) ||
isFunction(target, "kotlin", "Short", fName) ||
@@ -1522,7 +1702,7 @@ open class KotlinFileExtractor(
isFunction(target, "kotlin", "Double", fName)
}
- fun isArrayType(typeName: String) =
+ private fun isArrayType(typeName: String) =
when(typeName) {
"Array" -> true
"IntArray" -> true
@@ -1536,7 +1716,7 @@ open class KotlinFileExtractor(
else -> false
}
- fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) {
+ private fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) {
with("call", c) {
val target = tryReplaceSyntheticFunction(c.symbol.owner)
@@ -2101,6 +2281,22 @@ open class KotlinFileExtractor(
enclosingStmt: Label
): Label = extractNewExpr(useFunction(calledConstructor, constructorTypeArgs), constructedType, locId, parent, idx, callable, enclosingStmt)
+ private fun needsObinitFunction(c: IrClass) = c.primaryConstructor == null && c.constructors.count() > 1
+
+ private fun getObinitLabel(c: IrClass) = getFunctionLabel(
+ c,
+ null,
+ "",
+ listOf(),
+ pluginContext.irBuiltIns.unitType,
+ null,
+ functionTypeParameters = listOf(),
+ classTypeArgsIncludingOuterClasses = listOf(),
+ overridesCollectionsMethod = false,
+ javaSignature = null,
+ addParameterWildcardsByDefault = false
+ )
+
private fun extractConstructorCall(
e: IrFunctionAccessExpression,
parent: Label,
@@ -2153,8 +2349,6 @@ open class KotlinFileExtractor(
}
}
- private val loopIdMap: MutableMap> = mutableMapOf()
-
// todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
private val declarationStack: Stack = Stack()
@@ -2192,7 +2386,7 @@ open class KotlinFileExtractor(
}
}
- fun getStatementOriginOperator(origin: IrStatementOrigin?) = when (origin) {
+ private fun getStatementOriginOperator(origin: IrStatementOrigin?) = when (origin) {
IrStatementOrigin.PLUSEQ -> "plus"
IrStatementOrigin.MINUSEQ -> "minus"
IrStatementOrigin.MULTEQ -> "times"
@@ -2201,7 +2395,7 @@ open class KotlinFileExtractor(
else -> null
}
- fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
+ private fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
// Check for a desugared in-place update operator, such as "v += e":
return getStatementOriginOperator(origin)?.let {
if (updateRhs is IrCall &&
@@ -2216,7 +2410,7 @@ open class KotlinFileExtractor(
}
}
- fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean {
+ private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean {
when(origin) {
IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx)
@@ -2228,7 +2422,7 @@ open class KotlinFileExtractor(
return true
}
- fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean {
+ private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean {
/*
* We're expecting the pattern
* {
@@ -2299,7 +2493,7 @@ open class KotlinFileExtractor(
return false
}
- fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) {
+ private fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) {
extractExpression(e, callable, StmtParent(parent, idx))
}
@@ -2307,7 +2501,7 @@ open class KotlinFileExtractor(
extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt))
}
- fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) {
+ private fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) {
with("expression", e) {
when(e) {
is IrDelegatingConstructorCall -> {
@@ -2402,41 +2596,35 @@ open class KotlinFileExtractor(
}
}
is IrWhileLoop -> {
- val stmtParent = parent.stmt(e, callable)
- val id = tw.getFreshIdLabel()
- loopIdMap[e] = id
- val locId = tw.getLocation(e)
- tw.writeStmts_whilestmt(id, stmtParent.parent, stmtParent.idx, callable)
- tw.writeHasLocation(id, locId)
- extractExpressionExpr(e.condition, callable, id, 0, id)
- val body = e.body
- if(body != null) {
- extractExpressionStmt(body, callable, id, 1)
- }
- loopIdMap.remove(e)
+ extractLoop(e, parent, callable)
}
is IrDoWhileLoop -> {
- val stmtParent = parent.stmt(e, callable)
- val id = tw.getFreshIdLabel()
- loopIdMap[e] = id
- val locId = tw.getLocation(e)
- tw.writeStmts_dostmt(id, stmtParent.parent, stmtParent.idx, callable)
- tw.writeHasLocation(id, locId)
- extractExpressionExpr(e.condition, callable, id, 0, id)
- val body = e.body
- if(body != null) {
- extractExpressionStmt(body, callable, id, 1)
- }
- loopIdMap.remove(e)
+ extractLoop(e, parent, callable)
}
is IrInstanceInitializerCall -> {
- val stmtParent = parent.stmt(e, callable)
val irConstructor = declarationStack.peek() as? IrConstructor
if (irConstructor == null) {
logger.errorElement("IrInstanceInitializerCall outside constructor", e)
return
}
- extractInstanceInitializerBlock(stmtParent, irConstructor)
+ if (needsObinitFunction(irConstructor.parentAsClass)) {
+ val exprParent = parent.expr(e, callable)
+ val id = tw.getFreshIdLabel()
+ val type = useType(pluginContext.irBuiltIns.unitType)
+ val locId = tw.getLocation(e)
+ val methodLabel = getObinitLabel(irConstructor.parentAsClass)
+ val methodId = tw.getLabelFor(methodLabel)
+ tw.writeExprs_methodaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
+ tw.writeHasLocation(id, locId)
+ tw.writeCallableEnclosingExpr(id, callable)
+ tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
+ tw.writeCallableBinding(id, methodId)
+ }
+ else {
+ val stmtParent = parent.stmt(e, callable)
+ extractInstanceInitializerBlock(stmtParent, irConstructor)
+ }
}
is IrConstructorCall -> {
val exprParent = parent.expr(e, callable)
@@ -2556,78 +2744,22 @@ open class KotlinFileExtractor(
val exprParent = parent.expr(e, callable)
val owner = e.symbol.owner
if (owner is IrValueParameter && owner.index == -1 && !owner.isExtensionReceiver()) {
- val id = tw.getFreshIdLabel()
- val type = useType(e.type)
- val locId = tw.getLocation(e)
- tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
- tw.writeExprsKotlinType(id, type.kotlinResult.id)
- tw.writeHasLocation(id, locId)
- tw.writeCallableEnclosingExpr(id, callable)
- tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
-
-
- fun extractTypeAccess(parent: IrClass){
- extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
- }
-
- when(val ownerParent = owner.parent) {
- is IrFunction -> {
- if (ownerParent.dispatchReceiverParameter == owner &&
- ownerParent.extensionReceiverParameter != null) {
-
- val ownerParent2 = ownerParent.parent
- if (ownerParent2 is IrClass){
- extractTypeAccess(ownerParent2)
- } else {
- logger.errorElement("Unhandled qualifier for this", e)
- }
- }
- }
- is IrClass -> {
- if (ownerParent.thisReceiver == owner) {
- extractTypeAccess(ownerParent)
- }
- }
- else -> {
- logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
- }
- }
+ extractThisAccess(e, exprParent, callable)
} else {
- val id = tw.getFreshIdLabel()
- val type = useType(e.type)
- val locId = tw.getLocation(e)
- tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
- tw.writeExprsKotlinType(id, type.kotlinResult.id)
- tw.writeHasLocation(id, locId)
- tw.writeCallableEnclosingExpr(id, callable)
- tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
-
- val vId = useValueDeclaration(owner)
- if (vId != null) {
- tw.writeVariableBinding(id, vId)
- }
+ extractVariableAccess(useValueDeclaration(owner), e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
}
}
is IrGetField -> {
val exprParent = parent.expr(e, callable)
- val id = tw.getFreshIdLabel()
- val type = useType(e.type)
- val locId = tw.getLocation(e)
- tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
- tw.writeExprsKotlinType(id, type.kotlinResult.id)
- tw.writeHasLocation(id, locId)
- tw.writeCallableEnclosingExpr(id, callable)
- tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
val owner = tryReplaceAndroidSyntheticField(e.symbol.owner)
- val vId = useField(owner)
- tw.writeVariableBinding(id, vId)
- tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
-
- val receiver = e.receiver
- if (receiver != null) {
- extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
- } else if (owner.isStatic) {
- extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
+ val locId = tw.getLocation(e)
+ extractVariableAccess(useField(owner), e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { id ->
+ val receiver = e.receiver
+ if (receiver != null) {
+ extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
+ } else if (owner.isStatic) {
+ extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
+ }
}
}
is IrGetEnumValue -> {
@@ -2928,6 +3060,114 @@ open class KotlinFileExtractor(
}
}
+ private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label) {
+ val containingDeclaration = declarationStack.peek()
+ val locId = tw.getLocation(e)
+ val type = useType(e.type)
+
+ if (containingDeclaration.shouldExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) {
+ // Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference
+ // to the corresponding static object instance.
+ val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass)
+ extractVariableAccess(instanceField.id, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { varAccessId ->
+ extractStaticTypeAccessQualifier(containingDeclaration, varAccessId, locId, callable, exprParent.enclosingStmt)
+ }
+ } else {
+ val id = tw.getFreshIdLabel()
+
+ tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
+ tw.writeHasLocation(id, locId)
+ tw.writeCallableEnclosingExpr(id, callable)
+ tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
+
+ fun extractTypeAccess(parent: IrClass) {
+ extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
+ }
+
+ val owner = e.symbol.owner
+ when(val ownerParent = owner.parent) {
+ is IrFunction -> {
+ if (ownerParent.dispatchReceiverParameter == owner &&
+ ownerParent.extensionReceiverParameter != null) {
+
+ val ownerParent2 = ownerParent.parent
+ if (ownerParent2 is IrClass){
+ extractTypeAccess(ownerParent2)
+ } else {
+ logger.errorElement("Unhandled qualifier for this", e)
+ }
+ }
+ }
+ is IrClass -> {
+ if (ownerParent.thisReceiver == owner) {
+ extractTypeAccess(ownerParent)
+ }
+ }
+ else -> {
+ logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
+ }
+ }
+ }
+ }
+
+ private fun extractVariableAccess(variable: Label?, irType: IrType, locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) =
+ tw.getFreshIdLabel().also {
+ val type = useType(irType)
+ tw.writeExprs_varaccess(it, type.javaResult.id, parent, idx)
+ tw.writeExprsKotlinType(it, type.kotlinResult.id)
+ tw.writeHasLocation(it, locId)
+ tw.writeCallableEnclosingExpr(it, callable)
+ tw.writeStatementEnclosingExpr(it, enclosingStmt)
+
+ if (variable != null) {
+ tw.writeVariableBinding(it, variable)
+ }
+ }
+
+ private fun extractLoop(
+ loop: IrLoop,
+ stmtExprParent: StmtExprParent,
+ callable: Label
+ ) {
+ val stmtParent = stmtExprParent.stmt(loop, callable)
+ val locId = tw.getLocation(loop)
+
+ val idx: Int
+ val parent: Label
+
+ val label = loop.label
+ if (label != null) {
+ val labeledStmt = tw.getFreshIdLabel()
+ tw.writeStmts_labeledstmt(labeledStmt, stmtParent.parent, stmtParent.idx, callable)
+ tw.writeHasLocation(labeledStmt, locId)
+
+ tw.writeNamestrings(label, "", labeledStmt)
+ idx = 0
+ parent = labeledStmt
+ } else {
+ idx = stmtParent.idx
+ parent = stmtParent.parent
+ }
+
+ val id = if (loop is IrWhileLoop) {
+ val id = tw.getFreshIdLabel()
+ tw.writeStmts_whilestmt(id, parent, idx, callable)
+ id
+ } else {
+ val id = tw.getFreshIdLabel()
+ tw.writeStmts_dostmt(id, parent, idx, callable)
+ id
+ }
+
+ tw.writeHasLocation(id, locId)
+ extractExpressionExpr(loop.condition, callable, id, 0, id)
+ val body = loop.body
+ if (body != null) {
+ extractExpressionStmt(body, callable, id, 1)
+ }
+ }
+
private fun IrValueParameter.isExtensionReceiver(): Boolean {
val parentFun = parent as? IrFunction ?: return false
return parentFun.extensionReceiverParameter == this
@@ -3733,7 +3973,7 @@ open class KotlinFileExtractor(
}
}
- fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
+ private fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
with("vararg element", e) {
val argExpr = when(e) {
is IrExpression -> e
@@ -3925,7 +4165,7 @@ open class KotlinFileExtractor(
return initId
}
- fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
+ private fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) {
with("type operator call", e) {
when(e.operator) {
IrTypeOperator.CAST -> {
@@ -4201,7 +4441,7 @@ open class KotlinFileExtractor(
private fun extractBreakContinue(
e: IrBreakContinue,
- id: Label
+ id: Label
) {
with("break/continue", e) {
val locId = tw.getLocation(e)
@@ -4210,14 +4450,6 @@ open class KotlinFileExtractor(
if (label != null) {
tw.writeNamestrings(label, "", id)
}
-
- val loopId = loopIdMap[e.loop]
- if (loopId == null) {
- logger.errorElement("Missing break/continue target", e)
- return
- }
-
- tw.writeKtBreakContinueTargets(id, loopId)
}
}
@@ -4299,4 +4531,15 @@ open class KotlinFileExtractor(
declarationStack.pop()
}
}
+
+ private enum class CompilerGeneratedKinds(val kind: Int) {
+ DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS(1),
+ GENERATED_DATA_CLASS_MEMBER(2),
+ DEFAULT_PROPERTY_ACCESSOR(3),
+ CLASS_INITIALISATION_METHOD(4),
+ ENUM_CLASS_SPECIAL_MEMBER(5),
+ DELEGATED_PROPERTY_GETTER(6),
+ DELEGATED_PROPERTY_SETTER(7),
+ JVMSTATIC_PROXY_METHOD(8),
+ }
}
diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
index b5fcad1372d..982a11c5f68 100644
--- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
+++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt
@@ -49,7 +49,7 @@ open class KotlinUsesExtractor(
javaLangObject?.typeWith()
}
- fun usePackage(pkg: String): Label {
+ private fun usePackage(pkg: String): Label {
return extractPackage(pkg)
}
@@ -154,12 +154,12 @@ open class KotlinUsesExtractor(
} ?: argsIncludingOuterClasses
}
- fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
+ private fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
// Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class.
// For example, for (java syntax) `class A { static class B { class C { class D { } } } }`,
// `nonStaticParentsWithSelf(D)` = `[D, C, B]`.
- fun parentsWithTypeParametersInScope(c: IrClass): List {
+ private fun parentsWithTypeParametersInScope(c: IrClass): List {
val parentsList = c.parentsWithSelf.toList()
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) }
return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1)
@@ -168,14 +168,14 @@ open class KotlinUsesExtractor(
// Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for
// `class NotInScope { static class OutermostInScope { class QueryClass { } } }`,
// `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`.
- fun getTypeParametersInScope(c: IrClass) =
+ private fun getTypeParametersInScope(c: IrClass) =
parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten()
// Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`.
// Hack for the time being: the substituted types are always nullable, to prevent downstream code
// from replacing a generic parameter by a primitive. As and when we extract Kotlin types we will
// need to track this information in more detail.
- fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) =
+ private fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) =
getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap()
fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List) =
@@ -190,7 +190,7 @@ open class KotlinUsesExtractor(
}
// The Kotlin compiler internal representation of Outer.Inner.InnerInner.someFunction.LocalClass is LocalClass. This function returns [A, B, C, D, E, F, G, H, I, J].
- fun orderTypeArgsLeftToRight(c: IrClass, argsIncludingOuterClasses: List?): List? {
+ private fun orderTypeArgsLeftToRight(c: IrClass, argsIncludingOuterClasses: List?): List? {
if(argsIncludingOuterClasses.isNullOrEmpty())
return argsIncludingOuterClasses
val ret = ArrayList()
@@ -237,15 +237,15 @@ open class KotlinUsesExtractor(
return UseClassInstanceResult(classTypeResult, extractClass)
}
- fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray()
+ private fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray()
- fun extractClassLaterIfExternal(c: IrClass) {
+ private fun extractClassLaterIfExternal(c: IrClass) {
if (isExternalDeclaration(c)) {
extractExternalClassLater(c)
}
}
- fun extractExternalEnclosingClassLater(d: IrDeclaration) {
+ private fun extractExternalEnclosingClassLater(d: IrDeclaration) {
when (val parent = d.parent) {
is IrClass -> extractExternalClassLater(parent)
is IrFunction -> extractExternalEnclosingClassLater(parent)
@@ -254,7 +254,7 @@ open class KotlinUsesExtractor(
}
}
- fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
+ private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
if (isExternalFileClassMember(p)) {
extractExternalClassLater(p.parentAsClass)
dependencyCollector?.addDependency(p, externalClassExtractor.propertySignature)
@@ -262,7 +262,7 @@ open class KotlinUsesExtractor(
}
}
- fun extractFieldLaterIfExternalFileMember(f: IrField) {
+ private fun extractFieldLaterIfExternalFileMember(f: IrField) {
if (isExternalFileClassMember(f)) {
extractExternalClassLater(f.parentAsClass)
dependencyCollector?.addDependency(f, externalClassExtractor.fieldSignature)
@@ -270,7 +270,7 @@ open class KotlinUsesExtractor(
}
}
- fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
+ private fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
if (isExternalFileClassMember(f)) {
extractExternalClassLater(f.parentAsClass)
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
@@ -301,7 +301,7 @@ open class KotlinUsesExtractor(
externalClassExtractor.extractLater(c)
}
- fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
+ private fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
// The Android Kotlin Extensions Gradle plugin introduces synthetic functions, fields and classes. The most
// obvious signature is that they lack any supertype information even though they are not root classes.
// If possible, replace them by a real version of the same class.
@@ -503,7 +503,7 @@ open class KotlinUsesExtractor(
// but returns boxed arrays with a nullable, invariant component type, with any nested arrays
// similarly transformed. For example, Array> would become Array?>
// Array<*> will become Array.
- fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
+ private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
if (arrayType.isPrimitiveArray())
arrayType
else {
@@ -528,7 +528,7 @@ open class KotlinUsesExtractor(
)
}
- fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
+ private fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
// Ensure we extract Array as Integer[], not int[], for example:
fun nullableIfNotPrimitive(type: IrType) = if (type.isPrimitiveType() && !isPrimitiveArray) type.makeNullable() else type
@@ -579,7 +579,7 @@ open class KotlinUsesExtractor(
RETURN, GENERIC_ARGUMENT, OTHER
}
- fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
+ private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
if (s.abbreviation != null) {
// TODO: Extract this information
}
@@ -810,14 +810,14 @@ open class KotlinUsesExtractor(
return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f }
}
- fun getTypeParameters(dp: IrDeclarationParent): List =
+ private fun getTypeParameters(dp: IrDeclarationParent): List =
when(dp) {
is IrClass -> dp.typeParameters
is IrFunction -> getFunctionTypeParameters(dp)
else -> listOf()
}
- fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
+ private fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
when(it) {
is IrClass -> it
is IrFunction -> getEnclosingClass(it.parent)
@@ -924,7 +924,7 @@ open class KotlinUsesExtractor(
null
} ?: t
- fun getJavaTypeArgument(jt: JavaType, idx: Int) =
+ private fun getJavaTypeArgument(jt: JavaType, idx: Int) =
when(jt) {
is JavaClassifierType -> jt.typeArguments.getOrNull(idx)
is JavaArrayType -> if (idx == 0) jt.componentType else null
@@ -1146,15 +1146,6 @@ open class KotlinUsesExtractor(
return res
}
- fun useFunctionCommon(f: IrFunction, label: String): Label {
- val id: Label = tw.getLabelFor(label)
- if (isExternalDeclaration(f)) {
- extractFunctionLaterIfExternalFileMember(f)
- extractExternalEnclosingClassLater(f)
- }
- return id
- }
-
// These are classes with Java equivalents, but whose methods don't all exist on those Java equivalents--
// for example, the numeric classes define arithmetic functions (Int.plus, Long.or and so on) that lower to
// primitive arithmetic on the JVM, but which we extract as calls to reflect the source syntax more closely.
@@ -1162,7 +1153,7 @@ open class KotlinUsesExtractor(
"kotlin.Boolean", "kotlin.Byte", "kotlin.Char", "kotlin.Double", "kotlin.Float", "kotlin.Int", "kotlin.Long", "kotlin.Number", "kotlin.Short"
)
- fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
+ private fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
if (noReplace)
f
else
@@ -1210,20 +1201,24 @@ open class KotlinUsesExtractor(
} as IrFunction? ?: f
fun useFunction(f: IrFunction, classTypeArgsIncludingOuterClasses: List? = null, noReplace: Boolean = false): Label {
+ return useFunction(f, null, classTypeArgsIncludingOuterClasses, noReplace)
+ }
+
+ fun useFunction(f: IrFunction, parentId: Label?, classTypeArgsIncludingOuterClasses: List?, noReplace: Boolean = false): Label {
if (f.isLocalFunction()) {
val ids = getLocallyVisibleFunctionLabels(f)
return ids.function.cast()
- } else {
- val realFunction = kotlinFunctionToJavaEquivalent(f, noReplace)
- return useFunctionCommon(realFunction, getFunctionLabel(realFunction, classTypeArgsIncludingOuterClasses))
}
+ val javaFun = kotlinFunctionToJavaEquivalent(f, noReplace)
+ val label = getFunctionLabel(javaFun, parentId, classTypeArgsIncludingOuterClasses)
+ val id: Label = tw.getLabelFor(label)
+ if (isExternalDeclaration(javaFun)) {
+ extractFunctionLaterIfExternalFileMember(javaFun)
+ extractExternalEnclosingClassLater(javaFun)
+ }
+ return id
}
- fun useFunction(f: IrFunction, parentId: Label, classTypeArgsIncludingOuterClasses: List?, noReplace: Boolean = false) =
- kotlinFunctionToJavaEquivalent(f, noReplace).let {
- useFunctionCommon(it, getFunctionLabel(it, parentId, classTypeArgsIncludingOuterClasses))
- }
-
fun getTypeArgumentLabel(
arg: IrTypeArgument
): TypeResult {
@@ -1351,14 +1346,14 @@ open class KotlinUsesExtractor(
return "@\"typevar;{$parentLabel};${param.name}\""
}
- fun useTypeParameter(param: IrTypeParameter) =
+ private fun useTypeParameter(param: IrTypeParameter) =
TypeResult(
tw.getLabelFor(getTypeParameterLabel(param)),
useType(eraseTypeParameter(param)).javaResult.signature,
param.name.asString()
)
- fun extractModifier(m: String): Label {
+ private fun extractModifier(m: String): Label {
val modifierLabel = "@\"modifier;$m\""
val id: Label = tw.getLabelFor(modifierLabel, {
tw.writeModifiers(it, m)
@@ -1440,7 +1435,7 @@ open class KotlinUsesExtractor(
* Note that `Array` is retained (with `T` itself erased) because these are expected to be lowered to Java
* arrays, which are not generic.
*/
- fun erase (t: IrType): IrType {
+ private fun erase (t: IrType): IrType {
if (t is IrSimpleType) {
val classifier = t.classifier
val owner = classifier.owner
@@ -1464,7 +1459,7 @@ open class KotlinUsesExtractor(
return t
}
- fun eraseTypeParameter(t: IrTypeParameter) =
+ private fun eraseTypeParameter(t: IrTypeParameter) =
erase(t.superTypes[0])
/**
@@ -1493,7 +1488,7 @@ open class KotlinUsesExtractor(
fun useValueParameter(vp: IrValueParameter, parent: Label?): Label =
tw.getLabelFor(getValueParameterLabel(vp, parent))
- fun isDirectlyExposedCompanionObjectField(f: IrField) =
+ private fun isDirectlyExposedCompanionObjectField(f: IrField) =
f.hasAnnotation(FqName("kotlin.jvm.JvmField")) ||
f.correspondingPropertySymbol?.owner?.let {
it.isConst || it.isLateinit
@@ -1519,7 +1514,7 @@ open class KotlinUsesExtractor(
// otherwise two extension properties declared in the same enclosing context will get
// clashing trap labels. These are always private, so we can just make up a label without
// worrying about their names as seen from Java.
- val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it)}" } ?: ""
+ val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it).javaResult.id}" } ?: ""
return "@\"field;{$parentId};${extensionPropertyDiscriminator}${f.name.asString()}\""
}
diff --git a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
index 6eaa27b0ca4..8d844a65ec8 100644
--- a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
+++ b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt
@@ -1,14 +1,21 @@
package com.github.codeql
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.types.IrSimpleType
-import org.jetbrains.kotlin.ir.types.IdSignatureValues
-import org.jetbrains.kotlin.ir.util.IdSignature
+import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.name.FqName
class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContext) {
- fun getPrimitiveInfo(s: IrSimpleType) = mapping[s.classifier.signature]
+ fun getPrimitiveInfo(s: IrSimpleType) =
+ s.classOrNull?.let {
+ if ((it.owner.parent as? IrPackageFragment)?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME)
+ mapping[it.owner.name]
+ else
+ null
+ }
data class PrimitiveTypeInfo(
val primitiveName: String?,
@@ -60,25 +67,25 @@ class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContex
val javaLangVoid = findClass("java.lang.Void", kotlinNothing)
mapOf(
- IdSignatureValues._byte to PrimitiveTypeInfo("byte", true, javaLangByte, "kotlin", "Byte"),
- IdSignatureValues._short to PrimitiveTypeInfo("short", true, javaLangShort, "kotlin", "Short"),
- IdSignatureValues._int to PrimitiveTypeInfo("int", true, javaLangInteger, "kotlin", "Int"),
- IdSignatureValues._long to PrimitiveTypeInfo("long", true, javaLangLong, "kotlin", "Long"),
+ StandardNames.FqNames._byte.shortName() to PrimitiveTypeInfo("byte", true, javaLangByte, "kotlin", "Byte"),
+ StandardNames.FqNames._short.shortName() to PrimitiveTypeInfo("short", true, javaLangShort, "kotlin", "Short"),
+ StandardNames.FqNames._int.shortName() to PrimitiveTypeInfo("int", true, javaLangInteger, "kotlin", "Int"),
+ StandardNames.FqNames._long.shortName() to PrimitiveTypeInfo("long", true, javaLangLong, "kotlin", "Long"),
- IdSignatureValues.uByte to PrimitiveTypeInfo("byte", true, kotlinUByte, "kotlin", "UByte"),
- IdSignatureValues.uShort to PrimitiveTypeInfo("short", true, kotlinUShort, "kotlin", "UShort"),
- IdSignatureValues.uInt to PrimitiveTypeInfo("int", true, kotlinUInt, "kotlin", "UInt"),
- IdSignatureValues.uLong to PrimitiveTypeInfo("long", true, kotlinULong, "kotlin", "ULong"),
+ StandardNames.FqNames.uByteFqName.shortName() to PrimitiveTypeInfo("byte", true, kotlinUByte, "kotlin", "UByte"),
+ StandardNames.FqNames.uShortFqName.shortName() to PrimitiveTypeInfo("short", true, kotlinUShort, "kotlin", "UShort"),
+ StandardNames.FqNames.uIntFqName.shortName() to PrimitiveTypeInfo("int", true, kotlinUInt, "kotlin", "UInt"),
+ StandardNames.FqNames.uLongFqName.shortName() to PrimitiveTypeInfo("long", true, kotlinULong, "kotlin", "ULong"),
- IdSignatureValues._double to PrimitiveTypeInfo("double", true, javaLangDouble, "kotlin", "Double"),
- IdSignatureValues._float to PrimitiveTypeInfo("float", true, javaLangFloat, "kotlin", "Float"),
+ StandardNames.FqNames._double.shortName() to PrimitiveTypeInfo("double", true, javaLangDouble, "kotlin", "Double"),
+ StandardNames.FqNames._float.shortName() to PrimitiveTypeInfo("float", true, javaLangFloat, "kotlin", "Float"),
- IdSignatureValues._boolean to PrimitiveTypeInfo("boolean", true, javaLangBoolean, "kotlin", "Boolean"),
+ StandardNames.FqNames._boolean.shortName() to PrimitiveTypeInfo("boolean", true, javaLangBoolean, "kotlin", "Boolean"),
- IdSignatureValues._char to PrimitiveTypeInfo("char", true, javaLangCharacter, "kotlin", "Char"),
+ StandardNames.FqNames._char.shortName() to PrimitiveTypeInfo("char", true, javaLangCharacter, "kotlin", "Char"),
- IdSignatureValues.unit to PrimitiveTypeInfo("void", false, kotlinUnit, "kotlin", "Unit"),
- IdSignatureValues.nothing to PrimitiveTypeInfo(null, true, javaLangVoid, "kotlin", "Nothing"),
+ StandardNames.FqNames.unit.shortName() to PrimitiveTypeInfo("void", false, kotlinUnit, "kotlin", "Unit"),
+ StandardNames.FqNames.nothing.shortName() to PrimitiveTypeInfo(null, true, javaLangVoid, "kotlin", "Nothing"),
)
}()
}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/AutoCloseableUse.kt b/java/kotlin-extractor/src/main/kotlin/utils/AutoCloseableUse.kt
index fe68f308893..dad820ab6ee 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/AutoCloseableUse.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/AutoCloseableUse.kt
@@ -40,4 +40,4 @@ fun AutoCloseable?.closeFinallyAC(cause: Throwable?) = when {
} catch (closeException: Throwable) {
cause.addSuppressed(closeException)
}
-}
\ No newline at end of file
+}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
index 6f3954cfc34..15ca35a1438 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
@@ -68,7 +68,7 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? {
return null
}
-fun getRawIrClassBinaryPath(irClass: IrClass) =
+private fun getRawIrClassBinaryPath(irClass: IrClass) =
getIrClassVirtualFile(irClass)?.let {
val path = it.path
if(it.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL)
@@ -92,4 +92,4 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? {
}
fun getJavaEquivalentClassId(c: IrClass) =
- c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
\ No newline at end of file
+ c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt
index dce49790e0e..57a3e92e6b2 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt
@@ -55,7 +55,7 @@ private val specialFunctions = mapOf(
private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet()
-fun getSpecialJvmName(f: IrFunction): String? {
+private fun getSpecialJvmName(f: IrFunction): String? {
if (specialFunctionShortNames.contains(f.name) && f is IrSimpleFunction) {
f.allOverridden(true).forEach { overriddenFunc ->
overriddenFunc.parentClassOrNull?.fqNameWhenAvailable?.let { parentFqName ->
@@ -87,4 +87,4 @@ fun getJvmName(container: IrAnnotationContainer): String? {
}
}
return (container as? IrFunction)?.let { getSpecialJvmName(container) }
-}
\ No newline at end of file
+}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt
index 1349380cbc4..ca27217ac6c 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt
@@ -207,20 +207,6 @@ open class LoggerBase(val logCounter: LogCounter) {
}
open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
- private fun getDiagnosticLocation(): String? {
- val st = Exception().stackTrace
- for(x in st) {
- when(x.className) {
- "com.github.codeql.Logger",
- "com.github.codeql.FileLogger" -> {}
- else -> {
- return x.toString()
- }
- }
- }
- return null
- }
-
fun flush() {
tw.flush()
loggerBase.flush()
@@ -240,7 +226,7 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
loggerBase.info(tw, msg)
}
- fun warn(msg: String, extraInfo: String?) {
+ private fun warn(msg: String, extraInfo: String?) {
loggerBase.warn(tw, msg, extraInfo)
}
fun warn(msg: String, exn: Throwable) {
@@ -250,7 +236,7 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
warn(msg, null)
}
- fun error(msg: String, extraInfo: String?) {
+ private fun error(msg: String, extraInfo: String?) {
loggerBase.error(tw, msg, extraInfo)
}
fun error(msg: String) {
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt
index b249bb0091a..694b3dff289 100644
--- a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt
+++ b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt
@@ -37,7 +37,7 @@ fun IrType.substituteTypeArguments(params: List, arguments: Lis
else -> this
}
-fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType {
+private fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType {
if (substitutionMap.isEmpty()) return this
val newArguments = arguments.map {
@@ -100,7 +100,7 @@ private fun subProjectedType(substitutionMap: Map context.irBuiltIns.anyNType
is IrTypeProjection -> when(this.variance) {
@@ -111,7 +111,7 @@ fun IrTypeArgument.upperBound(context: IrPluginContext) =
else -> context.irBuiltIns.anyNType
}
-fun IrTypeArgument.lowerBound(context: IrPluginContext) =
+private fun IrTypeArgument.lowerBound(context: IrPluginContext) =
when(this) {
is IrStarProjection -> context.irBuiltIns.nothingType
is IrTypeProjection -> when(this.variance) {
@@ -200,7 +200,7 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument =
typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType
-fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
+private fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
if (l === r)
return true
if (l == null)
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Descriptors.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Descriptors.kt
deleted file mode 100644
index 77cd96d541d..00000000000
--- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Descriptors.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.github.codeql.utils.versions
-
-import com.github.codeql.KotlinUsesExtractor
-import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
-
-fun KotlinUsesExtractor.getIrStubFromDescriptor(generateStub: (DeclarationStubGenerator) -> TIrStub) : TIrStub? {
- logger.error("Descriptors not yet supported for Kotlin 1.7")
- return null
-}
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Descriptors.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Descriptors.kt
new file mode 100644
index 00000000000..45b2afcc858
--- /dev/null
+++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Descriptors.kt
@@ -0,0 +1,27 @@
+package com.github.codeql.utils.versions
+
+import com.github.codeql.KotlinUsesExtractor
+import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
+import org.jetbrains.kotlin.idea.MainFunctionDetector
+import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
+import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
+import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
+import org.jetbrains.kotlin.ir.util.SymbolTable
+import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
+
+@OptIn(ObsoleteDescriptorBasedAPI::class)
+fun KotlinUsesExtractor.getIrStubFromDescriptor(generateStub: (DeclarationStubGenerator) -> TIrStub) : TIrStub? =
+ (pluginContext.symbolTable as? SymbolTable) ?.let {
+ // Copying the construction seen in JvmIrLinker.kt
+ val mangler = JvmDescriptorMangler(MainFunctionDetector(pluginContext.bindingContext, pluginContext.languageVersionSettings))
+ val descriptorFinder = DescriptorByIdSignatureFinderImpl(
+ pluginContext.moduleDescriptor,
+ mangler,
+ DescriptorByIdSignatureFinderImpl.LookupMode.MODULE_ONLY
+ )
+ val stubGenerator = DeclarationStubGeneratorImpl(pluginContext.moduleDescriptor, it, pluginContext.irBuiltIns, descriptorFinder)
+ generateStub(stubGenerator)
+ } ?: run {
+ logger.error("Plugin context has no symbol table, couldn't get IR stub")
+ null
+ }
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/FileEntry.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/FileEntry.kt
similarity index 100%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/FileEntry.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/FileEntry.kt
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Functions.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Functions.kt
similarity index 100%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Functions.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Functions.kt
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt
similarity index 100%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Psi2Ir.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Types.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Types.kt
similarity index 100%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/Types.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Types.kt
diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/withHasQuestionMark.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/withHasQuestionMark.kt
similarity index 100%
rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0-RC/withHasQuestionMark.kt
rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/withHasQuestionMark.kt
diff --git a/java/ql/consistency-queries/calls.ql b/java/ql/consistency-queries/calls.ql
index 207d7bd45b3..78ebc3fa9a6 100644
--- a/java/ql/consistency-queries/calls.ql
+++ b/java/ql/consistency-queries/calls.ql
@@ -1,5 +1,10 @@
import java
from MethodAccess ma
-where not exists(ma.getQualifier()) and ma.getFile().isKotlinSourceFile()
+// Generally Kotlin calls will always use an explicit qualifier, except for calls
+// to the synthetic instance initializer , which use an implicit `this`.
+where
+ not exists(ma.getQualifier()) and
+ ma.getFile().isKotlinSourceFile() and
+ not ma.getCallee() instanceof InstanceInitializer
select ma
diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected
new file mode 100644
index 00000000000..51186ef7b15
--- /dev/null
+++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected
@@ -0,0 +1,83 @@
+a.kt:
+# 0| [CompilationUnit] a
+# 1| 1: [Class] A
+# 0| 1: [Method]
+# 0| 3: [TypeAccess] int
+# 0| 5: [BlockStmt] { ... }
+# 0| 0: [ReturnStmt] return ...
+# 0| 0: [IntegerLiteral] 42
+# 1| 2: [Constructor] A
+# 1| 5: [BlockStmt] { ... }
+# 1| 0: [SuperConstructorInvocationStmt] super(...)
+# 1| 1: [BlockStmt] { ... }
+# 2| 3: [Method] f1
+# 2| 3: [TypeAccess] int
+# 2| 5: [BlockStmt] { ... }
+# 2| 0: [ReturnStmt] return ...
+# 2| 0: [IntegerLiteral] 1
+b.kt:
+# 0| [CompilationUnit] b
+# 1| 1: [Class] B
+# 0| 1: [Method]
+# 0| 3: [TypeAccess] int
+# 0| 5: [BlockStmt] { ... }
+# 0| 0: [ReturnStmt] return ...
+# 0| 0: [UnsafeCoerceExpr]
+# 0| 0: [TypeAccess] int
+# 0| 1: [IntegerLiteral] 1
+# 1| 2: [Constructor] B
+# 1| 5: [BlockStmt] { ... }
+# 1| 0: [SuperConstructorInvocationStmt] super(...)
+# 1| 1: [BlockStmt] { ... }
+c.kt:
+# 0| [CompilationUnit] c
+# 1| 1: [Class] C
+# 0| 1: [Method]
+# 0| 3: [TypeAccess] Unit
+#-----| 4: (Parameters)
+# 0| 0: [Parameter] param
+# 0| 0: [TypeAccess] ProcessBuilder
+# 0| 5: [BlockStmt] { ... }
+# 0| 0: [ReturnStmt] return ...
+# 0| 0: [MethodAccess] start(...)
+# 0| -1: [VarAccess] param
+# 1| 2: [Constructor] C
+# 1| 5: [BlockStmt] { ... }
+# 1| 0: [SuperConstructorInvocationStmt] super(...)
+# 1| 1: [BlockStmt] { ... }
+d.kt:
+# 0| [CompilationUnit] d
+# 1| 1: [Class] D
+# 0| 2: [FieldDeclaration] String bar;
+# 0| -1: [TypeAccess] String
+# 0| 0: [StringLiteral] Foobar
+# 1| 3: [Constructor] D
+# 1| 5: [BlockStmt] { ... }
+# 1| 0: [SuperConstructorInvocationStmt] super(...)
+# 1| 1: [BlockStmt] { ... }
+e.kt:
+# 0| [CompilationUnit] e
+# 1| 1: [Class] E
+# 0| 1: [Method]
+# 0| 3: [TypeAccess] boolean
+# 0| 5: [BlockStmt] { ... }
+# 0| 0: [ReturnStmt] return ...
+# 0| 0: [MethodAccess] add(...)
+# 0| -1: [ClassInstanceExpr] new ArrayList